Unity3D基础41:状态机实现人物站立、跑步与后退动画切换

一、状态机的建立

大部分情况下,当游戏内玩家没有任何操作时,肯定都是站立不动的状态,然而事实上,玩家不可能和木头人一样完全静止,这样显得非常不真实,给玩家带来的体验当然也会很差,所以基本上所有有角色的游戏(纯2D游戏除外),角色的站立状态也都是有专门的动画的。

当然了,站立状态大部分情况下都会是默认状态,所以先设置一个站立的状态,并作为初始状态如下:

点击一下状态,添加动画并改名

  • Motion:选择播放的动画
  • Speed:动画播放速度(别忘了动画是否循环播放可以点击动画进行设置)
  • Mirror:是否反转动画
  • Cycle Offset:动画偏移
  • Foot IK:足部修正,防止在奇怪地形上走路足部不自然

这样当进入游戏时,角色就会开始自动播放站立动画了

二、动画过渡

之后当然还需要添加跑步和倒退的动画,步骤如下:

1:新建两个状态,并设置好对应动画

2:将这三个状态相互连接起来,右键状态点击Make Transition即可创建出连线,可以看出这条线是有向的

下面这张图的含义就是:如果当前玩家在站立状态,当条件满足XXX时,就可以过渡到前进状态

3:设置触发条件,比如说当玩家按下W键进行移动时,动画由站立转为跑步

  • Float:浮点类型参数,很少用
  • Int:整型参数,例如设置Speed参数,当其为0时切换到站立动画,为2时触发跑步动画,为1时触发走路动画
  • Bool:bool类型参数
  • Trigger:触发器,相当于一瞬间的冲击,收到“冲击”时触发动画转换,很常用(特别是后面讲到的AnyState大法)

4:连线绑定条件

  •  Has Exit Time:当动画播放完毕时,播放下一个动画,除此之外勾选之后动画会强制播放完毕才转到下一个状态,哪怕是下面的条件触发
  • Settings:动画过渡设置,例如玩家从攻击状态转为防御状态,这个过程既可以是平滑缓慢的,也可以是瞬间的,很难讲清楚具体设置方法建议自己调调看,一般来讲中间的蓝色范围越短动画转化的越迅速
  • Conditions:触发状态切换条件(或运算)
  • Solo/Mute:一般用于调试,Solo为当父状态有多条连线满足条件时,优先走这条,Mute是禁用

 

5:搞定

三、代码控制Animator

  • Animator.SetInteger("参数名", 值):修改整型参数
  • Animator.SetFloat("参数名", 值):修改浮点参数
  • Animator.SetBool("参数名", true/false):修改Bool参数
  • Animator.SetTrigger("参数名", true/false):触发器触发

然后就是写脚本苦力活了

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CdsLocation : MonoBehaviour
{
    public enum MyState
    {
        none,
        stand,
        run,
        back,
        attack,
        dead
    };
    MyState myState;
    private Transform myTran;
    private Animator myAnimator;
    private Vector3 lastUpd, nowUpd;
    void Start()
    {
        nowUpd = lastUpd = myTran.position;
    }
    void FixedUpdate()
    {
        nowUpd = myTran.position;
        CheckRun(lastUpd, nowUpd);
        lastUpd = myTran.position;
    }
    void CheckRun(Vector3 l, Vector3 r)
    {
        if (l == r || Time.time <= 0.2f)        //如果两帧之间玩家位置没有改变,说明当前玩家是站立状态
        {
            if (myState != MyState.stand)       //如果在之前不是站立状态,切换为站立状态并播放站立动画,下同
            {
                myAnimator.SetInteger("Speed", 0);
                myState = MyState.stand;
            }
        }
        else if (Vector3.Dot(myTran.forward, r - l) > 0)        //将玩家正前方方向向量与玩家两帧之间位置差向量进行点积
        {                                                   //如果点积为正,说明玩家是向前移动,否则是向后移动
            if (myState != MyState.run)
            {
                myAnimator.SetInteger("Speed", 4);
                myState = MyState.run;
            }
        }
        else
        {
            if (myState != MyState.back)
            {
                myAnimator.SetInteger("Speed", 2);
                myState = MyState.back;
            }
        }
    }
}

 

  • 0
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值