Rigibody Animator 控制角色移动 上台阶

1.水平移动应用动画跟运动,上台阶使用Rigibody

public class RigibodyMoveTest :MonoBehaviour
{
        private Rigidbody m_Rigidbody;
        private float m_InputH;
        private float m_InputV;
        private Animator m_Animator;
        private PhysicMaterial m_FrictionPhysics, m_MaxFrictionPhysics, m_SlippyPhysics;       // create PhysicMaterial for the Rigidbody
        private CapsuleCollider m_CapsuleCollider;
        private float m_ColliderRadius, m_ColliderHeight;        // storage capsule collider extra information        
        private Vector3 m_ColliderCenter;                      // storage the center of the capsule collider info        
        private Vector2 m_Input;
        private Vector3 m_MoveDir;
        private float m_Velocity;// velocity to apply to rigdibody

        public float stepOffsetEnd = 0.45;
        public float stepOffsetStart = 0f;
        public float stepSmooth = 4f;
        public LayerMask groundLayer = 1 << 0;
        public float moveSpeed = 1f;
        public bool useCustomRootMotion;
        public bool isStep;

        private void Init()
        {
            m_Animator = GetComponent<Animator>();
            m_Animator.updateMode = AnimatorUpdateMode.AnimatePhysics;
            // rigidbody info
            m_Rigidbody = GetComponent<Rigidbody>();
            // capsule collider info
            m_CapsuleCollider = GetComponent<CapsuleCollider>();
            // save your collider preferences 
            m_ColliderCenter = GetComponent<CapsuleCollider>().center;
            m_ColliderRadius = GetComponent<CapsuleCollider>().radius;
            m_ColliderHeight = GetComponent<CapsuleCollider>().height;
            
            CreatPhysicMaterial();
           
            // avoid collision detection with inside colliders 
            Collider[] AllColliders = this.GetComponentsInChildren<Collider>();
            for (int i = 0; i < AllColliders.Length; i++)
            {
                Physics.IgnoreCollision(m_CapsuleCollider, AllColliders[i]);
            }
        }
        
        void Start()
        {
            Init();
        }
        
        void Update()
        {
            m_InputH = Input.GetAxis("Horizontal");
            m_InputV = Input.GetAxis("Vertical");
            m_Input = new Vector2(m_InputH, m_InputV);
            if (m_Input.sqrMagnitude > 0.1f)
            {
                m_Animator.SetFloat("Forward", 1f);
            }
            else
            {
                m_Animator.SetFloat("Forward", 0f);
            }
            Vector3 vel = m_Rigidbody.velocity;
            m_MoveDir = new Vector3(m_InputH, 0f,m_InputV);
            if (Mathf.Abs(m_Input.x) > 0.05f || Mathf.Abs(m_Input.y) > 0.05f)
            {
                //给刚体更新新的向量速度
                //m_Rigidbody.velocity = new Vector3(m_Input.x * moveSpeed, vel.y, m_Input.y * moveSpeed);
                transform.rotation = Quaternion.LookRotation(new Vector3(m_Input.x, 0, m_Input.y));
            }
            isStep= StepOffset();
        }
        
        private void OnAnimatorMove()
        {
            if (Time.deltaTime == 0) return;
            if (useCustomRootMotion)
            {
                if (m_Input.magnitude > 0.1f)
                {
                    this.m_Velocity = moveSpeed;
                    var deltaPosition = new Vector3(m_Animator.deltaPosition.x, transform.position.y, m_Animator.deltaPosition.z);
                    Vector3 v = (deltaPosition * (m_Velocity > 0 ? m_Velocity : 1f)) / Time.deltaTime;
                    v.y = m_Rigidbody.velocity.y;
                    m_Rigidbody.velocity = Vector3.Lerp(m_Rigidbody.velocity, v, 20f * Time.deltaTime);
                }
                else
                {
                    transform.rotation = m_Animator.rootRotation;
                    transform.position = m_Animator.rootPosition;
                    m_Rigidbody.velocity = new Vector3(0f, m_Rigidbody.velocity.y, 0f);
                }
            }
            else
            {
                m_Animator.ApplyBuiltinRootMotion();
            }
        }
       
        private  bool StepOffset()
        {
            if (m_Input.sqrMagnitude < 0.1 /*|| !isGround*/) return false;
            var _hit = new RaycastHit();
            var _movementDirection = /*isStrafing && m_Input.magnitude > 0 ? (transform.right * m_Input.x + transform.forward * m_Input.y).normalized :*/ transform.forward;
            Ray rayStep = new Ray((transform.position + new Vector3(0, stepOffsetEnd, 0) + _movementDirection * ((m_CapsuleCollider).radius + 0.05f)), Vector3.down);
            if (Physics.Raycast(rayStep, out _hit, stepOffsetEnd - stepOffsetStart, groundLayer) && !_hit.collider.isTrigger)
            {
               if (_hit.point.y >= (transform.position.y) && _hit.point.y <= (transform.position.y + stepOffsetEnd))
               {
                   var _speed = Mathf.Clamp(m_Input.magnitude, 0, 1f);
                    var velocityDirection = (_hit.point - transform.position).normalized;
                    var vel = m_Rigidbody.velocity;
                    vel.y = (velocityDirection * stepSmooth * (_speed * (m_Velocity > 1 ? m_Velocity : 1))).y;
                    m_Rigidbody.velocity = vel;
                    return true;
               }
            }
            
            if (Physics.SphereCast(rayStep, m_CapsuleCollider.radius * 0.9f, out _hit, stepOffsetEnd - stepOffsetStart, groundLayer) && !_hit.collider.isTrigger)
            {
                if (_hit.point.y >= (transform.position.y) && _hit.point.y <= (transform.position.y + stepOffsetEnd))
                {
                    var _speed = Mathf.Clamp(m_Input.magnitude, 0, 1f);
                    var velocityDirection = (_hit.point - transform.position).normalized;
                    var vel = m_Rigidbody.velocity;
                    vel.y = (velocityDirection * stepSmooth * (_speed * (m_Velocity > 1 ? m_Velocity : 1))).y;
                    m_Rigidbody.velocity = vel;
                    return true;
                }
            }
            return false;
        }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值