利用混合树blend tree实现角色移动和奔跑之间的平滑过渡

功能效果:

所有动作的过渡都是平滑的

仅按下方向键时,角色行走,可由自然状态下过渡到行走动作

按下shift+方向键时,角色奔跑,可由自然状态下过渡到行走动作,再过渡到奔跑动作,也可由行走动作过渡到奔跑动作

当奔跑时,松开shift键,由奔跑动作过渡到行走动作,松开方向键,过渡到自然状态动作

 

关于blend tree这里不做多介绍,animator controller如下:

人物的移动控制脚本如下:

 public float realKeyHorizontal;
 public float realkeyVertical;
 private Animator currentAnimator;


void Start () {
	currentAnimator = transform.GetComponent<Animator> ();
	currentAnimator.applyRootMotion = true;
}

void FixedUpdate () {
        float keyVertical = 0;
        float keyHorizontal = 0;
        //键盘控制移动
        keyVertical = Input.GetAxis("Vertical") / 2f;
        keyHorizontal = Input.GetAxis("Horizontal") / 2f;


        if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift) )
        {   //加速奔跑
            isLeftDown = true;
            if (keyVertical > 0)
            {
                realkeyVertical += Time.deltaTime;
                if (realkeyVertical > 1) realkeyVertical = 1;
            }
            else if (keyVertical < 0) {
                realkeyVertical -= Time.deltaTime;
                if (realkeyVertical < -1) realkeyVertical = -1;
            }
            if (keyHorizontal > 0)
            {
                realKeyHorizontal += Time.deltaTime;
                if (realKeyHorizontal > 1) realKeyHorizontal = 1;
            }
            else if (keyHorizontal < 0)
            {
                realKeyHorizontal -= Time.deltaTime;
                if (realKeyHorizontal < -1) realKeyHorizontal = -1;
            }
        }
        else {
            // 1.行走(0.5)  2.行走到停止(0.5-0)  3.奔跑到行走(1-0.5)  4.奔跑到停止(1-0)
            isLeftDown = false;
            if (keyVertical != 0)
            {
                if (realkeyVertical > 0.5f) realkeyVertical -= Time.deltaTime;  //3、4
                else if (realkeyVertical < -0.5f) realkeyVertical += Time.deltaTime;  //3、4
                //else realkeyVertical = keyVertical;  //1、2
                else if (keyVertical > 0)
                {
                    realkeyVertical += Time.deltaTime;
                    if (realkeyVertical > 0.5f) realkeyVertical = 0.5f;
                }
                else if (keyVertical < 0){
                    realkeyVertical -= Time.deltaTime;
                    if (realkeyVertical < -0.5f) realkeyVertical = -0.5f;
                }
            }
            else {
                if (realkeyVertical > 0)
                {
                    realkeyVertical -= Time.deltaTime;
                    if (realkeyVertical < 0) realkeyVertical = 0;
                }
                else if (realkeyVertical < 0) {
                    realkeyVertical += Time.deltaTime;
                    if (realkeyVertical > 0) realkeyVertical = 0;
                }
            }

            if (keyHorizontal != 0)
            {
                if (realKeyHorizontal > 0.5f) realKeyHorizontal -= Time.deltaTime;  //3、4
                else if (realKeyHorizontal < -0.5f) realKeyHorizontal += Time.deltaTime;  //3、4
                //else realKeyHorizontal = keyHorizontal;  //1、2
                else if (keyHorizontal > 0)
                {
                    realKeyHorizontal += Time.deltaTime;
                    if (realKeyHorizontal > 0.5f) realKeyHorizontal = 0.5f;
                }
                else if (keyHorizontal < 0){
                    realKeyHorizontal -= Time.deltaTime;
                    if (realKeyHorizontal < -0.5f) realKeyHorizontal = -0.5f;
                }
            }
            else
            {
                if (realKeyHorizontal > 0)
                {
                    realKeyHorizontal -= Time.deltaTime;
                    if (realKeyHorizontal < 0) realKeyHorizontal = 0;
                }
                else if (realKeyHorizontal < 0)
                {
                    realKeyHorizontal += Time.deltaTime;
                    if (realKeyHorizontal > 0) realKeyHorizontal = 0;
                }
            }
        }

        currentAnimator.SetFloat ("forward", realkeyVertical);
		currentAnimator.SetFloat ("left_right", realKeyHorizontal);

    }

说明:

因为人物的移动属于物理控制,因此放在FixedUpdate方法中去执行,考虑到抖动或不平滑,所以realKeyHorizontal和realKeyVertical值的变动不能取一个比较小的增量变化如0.05,而是取Time.deltaTime。

realKeyHorizontal和realKeyVertical作为实际控制动画的参数

keyHorizontal和keyVertical作为移动开启或关闭的标志

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页