示例#1
0
        private void JumpSpeedProject(ref Vector4 velocity, ICharacterControllerContext controller)
        {
            var surfaceNormal = controller.GetLastGroundNormal();
            var tmpVec        = new Vector3(velocity.x, 0, velocity.z);
            var newVelocity   = GetDirectionTangentToSurfaceCustom(tmpVec, surfaceNormal, controller.transform.forward) * tmpVec.magnitude;

            //_logger.InfoFormat("before:{2}, after transform:{0}, project:{1}", newVelocity.ToStringExt(), Vector3.ProjectOnPlane(newVelocity, Vector3.up), velocity);
            newVelocity = Vector3.ProjectOnPlane(newVelocity, Vector3.up);
//            DebugDraw.EditorDrawArrow(controller.GetLastGroundHitPoint(),
//                new Vector3(velocity.x, 0, velocity.z).normalized, new Color(0.4f, 0.9f, 1f), 3f);
//            DebugDraw.EditorDrawArrow(controller.GetLastGroundHitPoint(),
//                new Vector3(newVelocity.x, 0, newVelocity.z).normalized * 2f, new Color(1f, 0.2f, 1f), 3f);
            //_logger.InfoFormat("prev:{0}, after:{1}, surfaceNormal:{2}", velocity.ToStringExt(),newVelocity.ToStringExt(), surfaceNormal.ToStringExt());

            velocity.x = newVelocity.x;
            velocity.z = newVelocity.z;
        }
示例#2
0
        private void CalculateVelocity(ref Vector4 velocity, ref Vector4 velocityOffset, ref float latestCollisionSlope,
                                       float deltaTime, PlayerEntity player, bool moveInWater, ICharacterControllerContext controller,
                                       Vector3 lastVel)
        {
            //坡度计算
            var lastNormal = controller.GetLastGroundNormal();

            // 最近一次与世界碰撞时碰撞点的法向
            latestCollisionSlope = Vector3.Angle(lastNormal, Vector3.up);

            //Debug.DrawRay(controller.GetLastGroundHitPoint(), lastNormal.normalized * 7,Color.yellow);

            Vector3 slopeVec = SlopeSlide(player, velocity, lastNormal, deltaTime);

            //Debug.DrawRay(controller.GetLastGroundHitPoint(), slopeVec.normalized * 7,Color.cyan);

            var xzcomp = Mathf.Sqrt(slopeVec.x * slopeVec.x + slopeVec.z * slopeVec.z);

            float collisionSlope = xzcomp == 0 ? 0 : slopeVec.y / xzcomp;


            var offsetSlope = Vector3.zero;

            //速度计算与下滑处理
            int ledgeDetect = -1;

            if (latestCollisionSlope >= controller.slopeLimit && Vector3.Dot(lastNormal, Vector3.up) > 0.0f &&
                (controller.collisionFlags & CollisionFlags.Below) != 0 &&
                lastVel.y <= 0.0f && (ledgeDetect = LedgeDetect(controller.GetLastGroundHitPoint(), controller.GetLastGroundNormal(),
                                                                controller.slopeLimit, controller.gameObject)) == 0
                )
            {
                // 沿斜面下滑
                velocity = slopeVec.ToVector4(); //SlopeSlide(player, -velocity.y, script.CollisionNormal, deltaTime);
                player.stateInterface.State.SetExceedSlopeLimit(true);
                //_logger.InfoFormat("slide slope!!!!!!, latestCollisionSlope:{0}", latestCollisionSlope);
            }
            else
            {
                var steepConfig = SingletonManager.Get <CharacterStateConfigManager>().SteepConfig;
                var buff        = steepConfig.CalcSteepBuff(player.playerMove.Steep) + (moveInWater ? -0.3f : 0) +
                                  player.playerMove.SpeedAffect;
                buff           = buff < -1.0f ? -1.0f : buff;
                velocity       = player.stateInterface.State.GetSpeed(lastVel, deltaTime, buff);
                velocityOffset = player.stateInterface.State.GetSpeedOffset(buff);
                velocity       = player.orientation.RotationYaw * (velocity);

                if (velocity.y < 0 &&
                    (Mathf.Abs(collisionSlope) > Mathf.Tan(MaxEdgeAngle * Mathf.Deg2Rad)) &&
                    (controller.collisionFlags & CollisionFlags.Below) != 0 && (ledgeDetect == -1 ? LedgeDetect(controller.GetLastGroundHitPoint(), controller.GetLastGroundNormal(),
                                                                                                                controller.slopeLimit, controller.gameObject):ledgeDetect) == 1)
                {
                    offsetSlope   = slopeVec;
                    offsetSlope.y = 0;
                    velocity.y    = slopeVec.y;
                    //_logger.InfoFormat("can not stand no ledge, ledgeDetect:{0}, collisionSlope:{1}, velocity:{2},offset:{3}, offsetSlope:{4},velocityOffset:{5}",
                    //   ledgeDetect,collisionSlope,
                    //  velocity.ToStringExt(),
                    //  (player.orientation.RotationYaw * (velocityOffset) + offsetSlope).ToStringExt(),
                    // offsetSlope.ToStringExt(),
                    // velocityOffset.ToStringExt());
                }

                else if (velocity.y < 0 &&
                         (Mathf.Abs(collisionSlope) < Mathf.Tan(controller.slopeLimit * Mathf.Deg2Rad)) && //超出限制应正常滑落
                         (controller.collisionFlags & CollisionFlags.Below) != 0
                         )                                                                                 //判断人物未浮空
                {
                    velocity.y = 0;
                    velocity.y = collisionSlope * velocity.magnitude - 0.1f; //-0.1f 保证下坡时持续产生CollisionFlags.Below
                    //_logger.InfoFormat("velocity:{0}, collisionSLocp:{1}, {2}, slopeVec:{3}, xzcomp:{4}", velocity.ToStringExt(), collisionSlope,Mathf.Tan(controller.slopeLimit * Mathf.Deg2Rad), slopeVec.ToStringExt() , xzcomp);
                }

                velocityOffset = player.orientation.RotationYaw * (velocityOffset) + offsetSlope;
                player.stateInterface.State.SetExceedSlopeLimit(false);
            }
        }