代码改变世界

unity5.x游戏开发指南6.3状态机

2016-01-08 16:12  疯狂的老八路  阅读(435)  评论(0)    收藏  举报

6.3.1Animator(动画)

1.创建动画控制器animator controller

Project视图下 crate->animator controller 重命名为playerControl

将新建的动画控制器拖入到player的属性视图的animator controller

2.打开animator视图

打开playerControlanimator视图,选中base layer动画层(可以点击+创建新的动画 层,一个动画层对应一个动画状态机。一般来说,不同的动画层控制身体的不同部分。)

3.创建跑步状态

图中每个长方形都是一个state状态,entry是初始状态。在编辑区点鼠标右键create  state->empty,创建新状态,命名为run.

将位于mecanim/animations/runs下的run动画指定到刚创建的run状态的motion栏。

这样就创建好了一个完整的带有动画的state

 6.3.2添加碰撞体

为player添加碰撞体character controller,将characttor controller所附带的胶囊碰撞体与热呢模型对齐。

character controller是一个继承自collider的类,,通过他及其附带的胶囊碰撞体(capsule collider)能很简单的处理碰撞二不需要刚体。

6.3.3添加摄像机

//摄像机所跟随的对象
    public Transform follow;
    //摄像机水平方向与对象的距离
    public float distanceAway;
    //摄像机垂直方向与对象的距离
    public float diatanceUp;
    //过滤速度
    public float smooth;
    //摄像机的目标速度
    private Vector3 targetPosition;
    //在LateUpdate中执行,确保在对象操作完成之后
    void LateUpdate() {
        //计算目标位置
        targetPosition = follow.position + Vector3.up - follow.forward * distanceAway;
        //对当前位置进行差值计算
        transform.position = Vector3.Lerp(transform.position,targetPosition,Time.deltaTime*smooth);
        //使摄像机观察物体
        transform.LookAt(follow);
 参考谷歌(http://blog.csdn.net/wuqinxiang/article/details/7979220    和   http://www.victsao.com/blog/97-unity/426-unity-script-lerp)

设置参数:
folllow:player游戏对象

distance away:5

distance up:2

smooth:3

6.34动作混合与控制

(一)动作混合

1.parameters中创建参数(点+号)

(float型)direction,speed,(bool型)jump

2.创建bleedTree混合树

双击Run状态进入bleedTree

右击bleedTree->add motion filed 添加动作,将位于Mecanim/Animations/runs下的动画文件runLeft指定到bleedTree属性栏的motion里,然后添加run和runRight.

修改门限值runleft(-1,1)run(0,1) runright(1,1)

(二)动作控制

   接口:Input.GetAxis():返回axis也就是控制轴的值,水平轴horizontal   垂直轴Vertical

     Animator.SetFloat(string name,float value,float dampTime,float deltaTime):设置animator的float参数来控制方向

     AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);得到animator中序号为0的layer,也就是base               layer的状态信息

1.将两接口结合,用键盘A/D或左右来控制角色

    private Animator animator;
    void Awake() {
        animator=GetComponent<Animator>();
    }
 // Update is called once per frame
 void Update () {
     //得到joystick水平轴向输入的值   joystick操纵杆
        float h = Input.GetAxis("Horizontal");
        //将该值传递至animator的direction参数
        animator.SetFloat("Direction",h,0.25f,Time.deltaTime);

 }

 

2.添加(Idle)休息状态 并添加动画

 建立run到idel链接 make transition

has exit time :播放到动画结束才切换状态   (取消勾选)

transition duration:0.02  转换所需时间

condition:speed greater;0.1  速度大于0时会从休息状态切换到跑步状态

建立idle到run链接

speed less 0.1  其他一样

 

3.添加jump状态并添加动画

run->jump

condition:jump  bool true

jump->run

要勾选has exit time

代码:

private Animator animator;
    void Awake() {
        animator=GetComponent<Animator>();
    }
 // Update is called once per frame
 void Update () {
        //得到joystick垂直轴向输入的值
        float v = Input.GetAxis("Vertical");
     //得到joystick水平轴向输入的值   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);
        //添加开火对Jump赋值
        //得到animator中序号为0的layer,也就是base layer的状态信息
        AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);
        if(stateInfo.shortNameHash==Animator.StringToHash("Run")){
            //Base Layer的状态为run,当检测到按下开火按钮,设置jump为run
            if (Input.GetButton("Fire1")) animator.SetBool("Jump",true);           
        }
        else{
            //当Base layer为其他状态时,设置jump为false
            animator.SetBool("Jump", false);

   }

 三.身体掩盖

1.创建一个avatar mask 叫rightArmMask并设置(object视图->crate->avatar mask)

 红色是遮罩部分,绿色是正常部分。(注意:除了那几个点之外身体线条的的颜色也是可以改变的。妈拉个屯,做的时候以为只能改变那几个点,浪费好长时间,日了狗了。)

2.回到animator视图,创建一个新的layer,并加上一个新的parameters参数Wave

(1)点齿轮设置:

weight:动画层的权重,默认的Base Layer必须为1。如果设置为0则当前层的动画不会播放,1则会播放,0-1之间会采用类似融合的情况来播放动画,比如之前的招手的例子,如果设置为0.5则招手动画播放时手部只会抬到脖子附近。

mask:动画遮罩,上方已经详解就不赘述。

blending:动画混合方式:

  • Override:覆盖,表示当前层的动画会覆盖掉其它层的动画,比如招手播放时右手就不能播放其它的动画了;
  • Additive:添加,表示当前层的动画的量添加到其它层的动画,比如招手播放时,手部奔跑或站立的甩动也会保留;
 (2)创建两个state,Empty和Wave,建立连接。

 empty->wave

取消 has exit time

condition:ware  true

wave->empty

勾选has exit time

添加代码 对animator 的wave赋值来控制挥手

//得到Animator中序号为1的layer,也就是rightArmLayer的状态信息
        AnimatorStateInfo stateInfo2 = animator.GetCurrentAnimatorStateInfo(1);
        if (stateInfo2.shortNameHash == Animator.StringToHash("Wave"))
        {
            //当RightArmLayer为挥手状态时
            animator.SetBool("Wave", false);
        }
        else {
            //当为其他状态时,按下鼠标右键挥手
            if(Input.GetButtonDown("Fire2")){
                animator.SetBool("Wave",true);
            }
        }