标签:
学习笔记适合新手,如有错误请指正。?号处也请各位指点下,谢谢。
状态机(State Machine)主要用作状态管理和状态切换,如跑、跳、休息等都是一个单独的状态,各自有对应的动画
Idle:休息状态
Run:跑步状态
Jump:跳跃状态
Animator
Controller增加Animator Controller,并重名为playerController
点击导航菜单栏》Window》Animator导航项,打开Animator视图
左上角显示选中Base Layer,即当前编辑的是Base Layer动画层,我们还可以点击“+”按钮创建新的动画层,一个动画层对应一个状态机,一般来说,不同的动画层控制身体的不同部分
图中每一个长方形图案都是一个State状态,其中Entry是初始状态
创建跑步状态:在编辑区域内点击鼠标右键》Create State》Empty
选中State》第一行我们重命名为Run》将动画文件制定至Motion一栏,这样我们就建好了一个完整的带有动画的State
运行场景,在Scene视图中,看见人物在场景中会一直向前跑动,但是人物会穿出墙外,我们还需要做3件事:
1增加碰撞体
2添加摄像机
3添加控制功能
添加碰撞体
Character Controller是一个继承自Collier的类,
点击Inspector最下方的Add Component按钮,搜索栏输入“Character Controller”并添加,并将Character Controller所发呆的胶囊体与人类模型对齐
添加摄像机
创建摄像机并添加名为ThirdPersonCan的脚本
using UnityEngine; using System.Collections; public class ThirdPersonCam : MonoBehaviour { //摄像机所跟随的对象 public Transform follow; //摄像机在水平方向与对象的距离 public float distanceAway; //摄像机在垂直方向与对象的距离 public float distanceUp; //过渡速度 public float smooth; //摄像机的目标速度 private Vector3 targetPosition; //在LateUpdate中执行摄像机操作,确保在对象的操作完成之后 void LateUpdate () { //计算目标位置 targetPosition = follow.position + Vector3.up * distanceUp - follow.forward * distanceAway; //对当前位置进行插值计算 transform.position = Vector3.Lerp(transform.position, targetPosition, Time.deltaTime * smooth); //使摄像机观察对象 transform.LookAt(follow); } }
将参数设置如下:
Follow:设置为player游戏对象
Distance Away:设置为5
Distance Up:设置为2
Smooth:设置为3
动作混合与控制
动作混合是动画系统中比较重要的功能
例如:人物有向前跑的动作和向左侧跑的动作,将两者混合就是向左方跑的动作了
1动作混合
回到Animator视图
创建一个名为Direction的float参数(设置BlendTree混合树的时候会用到)
在Animator的左上角点击Parameters标签,进入Animator的参数表视图》点击“+”》“Float”按钮创建参数并起名“Direction”
用同样的方法创建float参数“Speed”,改参数在之后从Idle和Run的状态间切换时会用到
最后创建Bool参数Jump,该参数在之后从Run到Jump的状态间切换时会用到
创建好Direction参数,创建Blend Tree,Blend Tree是不同动画的混合
选中Run状态,右键》“Create New BlendTree In State”按钮》双击Run状态进入BlendTree
点击“+”》“Add Motion Field”按钮添加动作,并将动画文件指定至图Motion一栏,然后继续添加Run和Run Right动作
Parameter参数一栏通过右侧的三角形下拉菜单选择之前创建的Direction参数,该参数决定着动作如何混合,在这里可理解为角色是向左跑还是向右跑
点击波形图下方的“0”。并输入-1.
波形图中左侧第一个三角形代表RunLeft,中间的陂型代表Run,右侧的波形代表RunRight,使用Rarameter Direction控制的
当为-1时,RunLeft向左跑动画
当为0时向前跑
当为1时是向右跑
当为之间的值时,比如0.5是向前跑和向右跑的混合,也就是向右前方跑
2动作控制
输入控制部分,我们主要用到Input.GetAxis()和Animator.SetFloat()这两个借口
Input.GetAxis():返回axis,也就是控制轴的值,
也可以通过点击导航菜单栏》Edit》Project Setting》Input菜单进入输入设置界面,在这个界面里,我们不仅可以定义水平轴和垂直轴的名称和参数,还可以定义其他按钮的名称和参数
GetAxis返回的值域是-1到1
Animator.SetFloat():设置Animator的float参数
例如,Run这个BlendTree中的Direction就可以通过这个参数来设置
它的函数签名是public void SetFloat(string name,Float value,float dampTime,float deltaTime);
Name:参数的名称
Value:值
dampTime:参数到达该值所需要的时间
deltaTime:上一帧所消耗的时间
例如:
Animator.SetFloat("Direction",x);
animator.SetFloat("Direction",x,0.25f,Time.deltaTime);
接下来把Input.GetAxis()和animator.SetFloat()这两个接口结合了,创建一个名为“PlayerManager”的脚本,添加到player游戏对象上
using UnityEngine; using System.Collections; public class PlayerManager_1 : MonoBehaviour { private Animator animator; void Awake() { animator = GetComponent<Animator>(); } void Update () { //得到Joystick水平轴向输入的值 float h = Input.GetAxis("Horizontal"); //将该值传递至animator的Direction参数 animator.SetFloat("Direction", h, 0.25f, Time.deltaTime); } }
运行场景,可以用键盘的A/D键或者左箭头右箭头来控制角色,可以通过Animator视图观察状态变化
接下来我们在添加(Idle)休息状态,并将动画文件赋予Idle的栏
在代码中通过垂直轴对Speed赋值的功能
using UnityEngine; using System.Collections; public class PlayerManager_2 : MonoBehaviour { private Animator animator; void Awake() { animator = GetComponent<Animator>(); } void Update () { //得到Joystick水平轴向输入的值 float v = Input.GetAxis("Vertical"); //得到Joystick水平轴向输入的值 float h = Input.GetAxis("Horizontal"); //将该值传递至animator的Speed参数 animator.SetFloat("Speed", h*h+v*v); //将该值传递至animator的Direction参数 animator.SetFloat("Direction", h, 0.25f, Time.deltaTime); } }
运行游戏,开始时角色在休息状态,按W/D不在移动,因为需要从垂直轴向得到的Speed才能从休息状态切换到跑步状态
最后添加jump状态,本例设定需要移动的助跑才能跳,也就是不能从休息状态切换到跳跃状态,只能从跑动状态切换至跳跃状态
添加开火按钮,代码如下:
using UnityEngine; using System.Collections; public class PlayerManager_3: MonoBehaviour { private Animator animator; void Awake() { //得到Animator组件 animator = GetComponent<Animator>(); } void Update () { //得到Joystick水平轴向输入的值 float v = Input.GetAxis("Vertical"); //得到Joystick水平轴向输入的值 float h = Input.GetAxis("Horizontal"); //将该值传递至animator的Speed参数 animator.SetFloat("Speed", h*h+v*v); //将该值传递至animator的Direction参数 animator.SetFloat("Direction", h, 0.25f, Time.deltaTime); //得到Animator中序号为0的layer,也就是Base Layer的状态信息 AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0); if (stateInfo.shortNameHash == Animator.StringToHash("Run")) { //Base Layer为Run状态,当检测到按下开火按钮,设置Jump为true if (Input.GetButton("Fire1")) animator.SetBool("Jump", true); } else { //当Base Layer为其他状态时,设置Jump为false animator.SetBool("Jump", false); } } }
运行场景,角色已经可以跳了,但是依然存在两个问题
当角色跳跃时,我们观察Scene视图,发现在跳跃时角色身体会缩成一团,但是绿色的碰撞体却没有相应的变化
从平台上跳下,并没有落地却已回到跑步状态
待续。。。。。。。。。。。。2015-11-16
标签:
原文地址:http://www.cnblogs.com/kubll/p/4970606.html