必威体育Betway必威体育官网
当前位置:首页 > IT技术

Unity3D - 【Animator】骨骼动画的实现

时间:2019-06-26 15:42:06来源:IT技术作者:seo实验室小编阅读:67次「手机版」
 

骨骼动画

利用Animator实现骨骼动画

1> 确保人物能够正常移动、Camera能够正常跟随

2> 使用WSAD对人物不同运动状态进行切换与连接

3> LeftShift:加速、Space:跳跃

4> 对于移动所产生的场景旋转以及视野跟随问题解决,可以参考我的另一篇文章:https://blog.csdn.net/qq_42292831/article/details/84400575

5> 模型资源下载请访问游戏蛮牛官网 ( http://www.manew.com )

****************************************************************************************************************************************

一:运行效果

二:操作以及注意事项

0> 首先需要在Anumator中选择自己新建的Animator controller文件:

1> 在Project中的动画文件夹中创建Animator Controller (状态控制机),双击打开

2> 设置左侧这些Float变量的目的:

拿W_Code举例:

当W键按下时,W_Code的键值就会变为1,松开按键,键值为0,这样人物的状态会切换为Walk状态;而且因为W还在Input.GetAxis("Vertical")的影响下沿着世界坐标的Z轴移动,Idle->Walk之间的切换完全依靠W键来确定。

3> 右侧箭头表示各个动作之间可以转换的方向与条件

这里就拿Run->Jump这个箭头举例,在Run的状态下当出现Jump_Code>0(1)时,就会触发跳跃动画

4> 注意事项:

在本Demo中出现了这样的情况:给人物与其他物体均添加的刚体属性,而且Camera属于人物的子物体,当两个刚体碰撞,Camera视角会莫名出现旋转。

取消被碰撞物体的刚体属性即可解决这种问题;

三:Scripts

1> 视角跟随:直接将Camera作为人物的子物体即可实现Camera的视角跟随

2> 视角移动:右键实现Camera视野左右移动(上下可将代码中的欧拉角指向y,但是范围过大而且无法更改,这里使用了x)

因为Camera是作为人物的子物体,所以将该脚本直接拖动到人物上将会直接是人物转向与Camera转向同步;

Camera_Follow.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Camera_Follow : MonoBehaviour {

    public Transform Camera;
    bool Model_IsRotate = false;
    // Use this for initialization
    void Start () {
		
	}
	
	// Update is called once per frame
	void Update () {
        if (Input.GetMouseButtonDown(1))
        {
            Model_IsRotate = true;
        }
        if (Input.GetMouseButtonUp(1))
        {
            Model_IsRotate = false;
        }
        if (Model_IsRotate)
        {
            transform.Rotatearound(transform.position, vector3.up, 10 * Input.GetAxis("Mouse X"));

            Vector3 originPosition = Camera.position;
            Quaternion originRotation = Camera.rotation;

            Camera.RotateAround(transform.position, transform.right, -10 * Input.GetAxis("Mouse Y"));
            if (Camera.eulerAngles.x < 0 || Camera.eulerAngles.x > 50)    //不明觉厉的欧拉角,但是能够设置x/y值来达到仰视和俯视的效果
            {
                Camera.position = originPosition;
                Camera.rotation = originRotation;
            }

        }
	}
}

3> 人物移动 (控制Animator键值进行状态转换)

Roko_Movement.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class Roko_Movement : MonoBehaviour {

    //public NavMeshAgent agent;
    public Animator anim;
    public float wsad_MoveSpeed = 10;

    bool Space_Key_Down = false;
    bool Left_Shift_Key_Down = false;
    bool W_Key_Down = false;
    bool S_Key_Down = false;
    bool A_Key_Down = false;
    bool D_Key_Down = false;

    // Use this for initialization
    void Start () {
		
	}
	// Update is called once per frame
	void Update () {
        //if(Input.GetMouseButtonDown(0))
        //      {
        //          Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        //          RaycastHit hit;
        //          if(Physics.Raycast(ray,out hit))
        //          {
        //              agent.SetDestination(hit.point);

        //          }
        //      }
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");
        this.transform.Translate(new Vector3(h, 0, v) * Time.deltaTime * wsad_MoveSpeed);
        
        //W键控制行走
        if (Input.GetKeyDown(KeyCode.W))
        {
            W_Key_Down = true;
        }
        if (Input.GetKeyUp(KeyCode.W))
        {   
            W_Key_Down = false;
        }
        if (W_Key_Down)
        {
            anim.SetFloat("W_Code", 1f);
        }
        if (!W_Key_Down)
        {
            anim.SetFloat("W_Code", 0f);
        }

        //S键控制后退
        if (Input.GetKeyDown(KeyCode.S))
        {
            S_Key_Down = true;
        }
        if (Input.GetKeyUp(KeyCode.S))
        {
            S_Key_Down = false;
        }
        if (S_Key_Down)
        {
            anim.SetFloat("S_Code", 1f);
        }
        if (!S_Key_Down)
        {
            anim.SetFloat("S_Code", 0f);
        }

        //A键控制左转
        if (Input.GetKeyDown(KeyCode.A))
        {
            A_Key_Down = true;
        }
        if (Input.GetKeyUp(KeyCode.A))
        {
            A_Key_Down = false;
        }
        if (A_Key_Down)
        {
            anim.SetFloat("A_Code", 1f);
        }
        if (!A_Key_Down)
        {
            anim.SetFloat("A_Code", 0f);
        }

        //D键控制左转
        if (Input.GetKeyDown(KeyCode.D))
        {
            D_Key_Down = true;
        }
        if (Input.GetKeyUp(KeyCode.D))
        {
            D_Key_Down = false;
        }
        if (D_Key_Down)
        {
            anim.SetFloat("D_Code", 1f);
        }
        if (!D_Key_Down)
        {
            anim.SetFloat("D_Code", 0f);
        }


        //Left_Shift键加速
        if (Input.GetKeyDown(KeyCode.LeftShift))
        {
            Left_Shift_Key_Down = true;
        }
        if (Input.GetKeyUp(KeyCode.LeftShift))
        {
            Left_Shift_Key_Down = false;
        }
        if (Left_Shift_Key_Down)
        {
            anim.SetFloat("Speed_up_Code", 1f);
        }
        if (!Left_Shift_Key_Down)
        {
            anim.SetFloat("Speed_up_Code", 0f);
        }

        //Space键控制Jump
        if (Input.GetKeyDown(KeyCode.Space))
        {
            Space_Key_Down = true;
        }
        if (Input.GetKeyUp(KeyCode.Space))
        {
            Space_Key_Down = false;
        }
        if (Space_Key_Down)
        {
            anim.SetFloat("Jump_Code", 1f);
        }
        if (!Space_Key_Down)
        {
            anim.SetFloat("Jump_Code", 0f);
        }

        //anim.SetFloat("Speed", agent.velocity.magnitude);
    }
}

【2019.01.20】更新

关于跳跃部分:

改进效果:按一下Space键,跳跃执行一次(不会在跳跃中途终止),并实现跳跃结束动作与其他动作的完美衔接。

首先设置终止时间,然后拖动时间进度条,使得在跳跃动画未结束的时候执行向Idle动画的返回,以实现动画的过渡。

----------------------人物模型下载:游戏蛮牛官网 ( http://www.manew.com )----------------------

相关阅读

分享到:

栏目导航

推荐阅读

热门阅读