github: https://github.com/lucaschen1993/PRG_DEMO

前言

在之前写状态机文章的时候介绍过,基于事件与委托实现的状态机。这篇文章将介绍状态机的使用,以及人物动画的实现,以及状态的切换。

角色 Animator Controller

我自己找了一个资源包是带动画的,但是要自己添加一个Animator Contoller,然后自己给这个动画控制器添加动画,这里我已经做好了,,废话不多说,直接上图。

这里的Attack状态我使用了子状态机,因为攻击动画不止一个,我又不想整个Base Layer看起来太凌乱,就使用了子状态机(Sub_stateMachine)。

另外的Move我使用了混合树,为了通过计算EasyTouch的摇杆的轴值来控制动画播放走还是跑。

这里有5个参数,MoveFactor是控制就是上面说的,控制角色播放跑还是走的动画,因为使用混合树,可以混合好walk与run的动画。Death是控制死亡动画播放的Trigger,AttackFactor是控制播放哪个攻击动画,ToIdle是回到Idle动画。Jump暂时没有做,但是方法也是一样的,先把Move Death,Attack这些比较重要的先做出来吧。

角色的状态控制以及动画控制

这里开始介绍控制角色的代码,先贴一些Player.cs的参数

 public delegate void PlayerStateChange(AllCharacter.StateType stateType);public event PlayerStateChange StateChange;public int PlayerHp;public float AtkCoolDown;private float attackCoolDownTime;private AllCharacter.StateType playerType;public FiniteStateMachine FsMachine;public ETCJoystick MoveJoystick;private Animator _anim;private NavMeshAgent _nav;

delegate与event是角色状态切换的事件与委托;AtkCoolDown与attackCoolDownTime用于制作攻击间隔;MoveJoystick是为了获取EasyTouch的摇杆,为了得到摇杆轴值。
在初始化Start的时候设置好角色的初始值,

    void Start(){//设置角色的初始状态PlayerHp = 100;_anim = GetComponentInChildren<Animator>();_nav = GetComponent<NavMeshAgent>();EnterStand();playerType = FsMachine.CurBaseState.GetStateType();attackCoolDownTime = 0;AtkCoolDown = 2.5f;}

接着在Update里面是状态控制,因为有些参数是要在某些状态内才计算的,所以我在这里使用了switch做状态判断。但是不控制状态的切换。例如攻击冷却间隔只在攻击状态下才会进行计算。由于角色挂了,就啥都不能做了,所以我就把角色的死亡放在switch外。(不过突然觉得这个不是很好,得找个时间修改一下)

    void Update (){FsMachine.OnUpdate();if (IsPlayerDead()){StateChange(StateType.STATE_DEAD);}switch (playerType){case StateType.STATE_ATTACK:attackCoolDownTime += Time.deltaTime;break;case StateType.STATE_STAND:break;case StateType.STATE_DEAD:break;case StateType.STATE_MOVE:break;}        }

这里使用的EasyTouch按钮通过ETCHolder.cs控制,我就不详细讲了,直接看代码就行。
ETCHolder.cs

using System.Collections;
using System.Collections.Generic;
using HedgehogTeam.EasyTouch;
using UnityEngine;public class ETCHolder : MonoBehaviour
{private Player _player;// Use this for initializationvoid Start (){_player = GameObject.Find("Player").GetComponent<Player>();}// Update is called once per framevoid Update () {}public void OnMoveStart(){_player.StickMove();}public void OnTouchUp(){//松开JoyStick,回到Stand状态,Idle_player.EnterStand();}public void OnAttackDown(){_player.DownAttack();}
}

在这里是直接调用Player里面的方法进行状态切换的,而状态的切换都是通过事件StateChange进行切换的

    public void StickMove(){//进入移动状态StateChange(AllCharacter.StateType.STATE_MOVE);}public void DownAttack(){//进入攻击状态StateChange(AllCharacter.StateType.STATE_ATTACK);}public void EnterStand(){//进入Stand状态,IdleStateChange(AllCharacter.StateType.STATE_STAND);}

接下讲一下获取Joystick的轴值以及用该轴值控制动画的播放。先贴一部分代码

    //获取ETCJoystick轴值public Vector3 GetJoystickAxis(){float h = MoveJoystick.axisX.axisValue;float v = MoveJoystick.axisY.axisValue;return new Vector3(h,0,v);}public void SetMoveFactor(float factor){_anim.SetFloat("MoveFactor",factor);}

这里直接通过Joystick的axisX.axisValue、axisY.axisValue就可以获取轴值了,返回的是一个Vector3的向量,接着通过这个返回值来计算其长度再赋值给moveFactor。
MoveState.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class MoveState : BaseState
{private readonly Player _player;public MoveState(Player player){this._player = player;}public override AllCharacter.StateType GetStateType(){return AllCharacter.StateType.STATE_MOVE;}public override void EnterState(FiniteStateMachine fsMachine, BaseState preState){if (preState != null){//Debug.Log("Enter the MoveState the preState is:" + preState.GetStateType());}else{//Debug.Log("Enter the MoveState");}_player.SetType(AllCharacter.StateType.STATE_MOVE);//Debug.Log(_player.CurBaseState);}public override void UpdateState(){Vector3 v3 = _player.GetJoystickAxis();float moveFactor = Vector3.Magnitude(v3);_player.SetMoveFactor(moveFactor);//Debug.Log("I'm Moving.");}public override void ExitState(BaseState preState){_player.SetMoveFactor(0f);//Debug.Log("Exit Move State. " + preState.GetStateType());}public override void InputHandle(){}
}

这样就可以通过轴值来控制动画的播放了。当摇杆偏移量小的时候是播放walk动画,当偏移量拉满的时候是播放run动画,当该偏移量在这之间,则是播放run与walk的混合动画。
接着是Attack的状态,以及攻击间隔的制作。
我们在Player的update中,已经计算了attackCoolDownTime,每进行一次攻击,就要重置一次攻击冷却时间;在计算攻击冷却时间的时候需要判断,攻击间隔是否大于默认的攻击冷却时间AtkCoolDown,接着能攻击了,就调用Attack。

    //随机攻击动画#region RandomAttack_animationpublic void ResetAttackCoolDown(){attackCoolDownTime = 0;}public bool CanAttack(){if (attackCoolDownTime > AtkCoolDown){ResetAttackCoolDown();return true;}return false;}public void Attack(){StartCoroutine(AttarCoroutine());}private IEnumerator AttarCoroutine(){int atkFactor = Random.Range(1, 3);_anim.SetInteger("AttackFactor", atkFactor);yield return null;_anim.SetInteger("AttackFactor", 0);}public void StopAttack(){_anim.SetInteger("AttackFactor", 0);}

AttackState.cs

using System.Collections;
using System.Collections.Generic;
using BehaviorDesigner.Runtime.Tasks.Basic.Math;
using UnityEngine;public class AttackState : BaseState
{private readonly Player _player;public AttackState(Player player){//向状态机发送事件,请求转换状态this._player = player;}public override AllCharacter.StateType GetStateType(){return AllCharacter.StateType.STATE_ATTACK;}public override void EnterState(FiniteStateMachine fsMachine, BaseState preState){if (preState != null){Debug.Log("Enter the AttackState the preState is:" + preState.GetStateType());}else{Debug.Log("Enter the AttackState");}_player.SetType(AllCharacter.StateType.STATE_ATTACK);_player.ResetAttackCoolDown();_player.Attack();//Debug.Log(_player.CurBaseState);}public override void UpdateState(){//战斗状态不间断平A//Debug.Log("I'm in Battle Mode .");bool canAttack = _player.CanAttack();//攻击间隔if (canAttack){_player.Attack();}}public override void ExitState(BaseState preState){_player.StopAttack();_player.ResetAttackCoolDown();Debug.Log("Exit Attack State. " + preState.GetStateType());}public override void InputHandle(){}
}

在进入攻击状态时要先执行一次攻击,不然就要等默认攻击冷却过后才能进行一次攻击,每次退出状态的时候攻击冷却时间清零。防止下一次攻击的时候该时间混乱。
这样,人物的状态切换动画制作就已经做完啦,给个成品gif。

总结

其实这里人物的动画以及状态切换是比较简单的,因为逻辑并不复杂。看上面的代码其实很清晰就清楚,哪个状态在干啥,通过哪个按键切换到哪个状态。下一篇将介绍一下用状态机制作的游戏AI。

ps:文章没办法面面俱到,所以有啥问题尽管私信我,我会一一回答。

用状态机做人物(AI)的状态切换以及动画效果——人物动画以及切换相关推荐

  1. echart 折线从左到右动画效果_echarts之自动切换折线图

    echarts有legend控件可以控制多个折线图之间的切换 legend: { data: ['财经','娱乐','社会'], selectedMode: "single", / ...

  2. 人物照片墙html模板,制作散落照片墙效果人物照片的PS教程

    今天教大家制作由多张拍立得照片组成的散落叠加的效果,方法很简单,特别适合新手学习 先看看效果图 一.首先我们将素材文件拖拽进PS,然后将背景图层也拖拽进去,层次在素材文件之上 二.好的接下来我们创建两 ...

  3. jq动画效果(图片左右大小切换,轮播)

    图片左右移动,移动距离为图片现在显示的大小,移动方向为图片隐藏部分的方向,图片在左隐藏时向右切换先把图片位置移动到最左边 轮播图 var lang=$(".num>li"). ...

  4. swiftui动画之tab自定义切换动画_vue 基础-动画过渡 transition 示例

    前言 <vue 基础>系列是再次回炉 vue 记的笔记,除了官网那部分知识点外,还会加入自己的一些理解.(里面会有大部分和官网相同的文案,有经验的同学择感兴趣的阅读) 讲到动画,说真的我自 ...

  5. ios 视图切换动画效果

    http://wangjun.easymorse.com/?p=1147 在ios view与view间切换的动画效果这篇文章中简单介绍了一种动画效果,下面我详细介绍一下ios中页面间跳转系统自带的动 ...

  6. 360金融首席科学家张家兴:只靠AI Lab做不好AI中台 | 独家专访

    「AI 技术生态论」 人物访谈栏目是 CSDN 发起的百万人学 AI 倡议下的重要组成部分.通过对 AI 生态顶级大咖.创业者.行业 KOL 的访谈,反映其对于行业的思考.未来趋势判断.技术实践,以及 ...

  7. 简历解析步骤(第二步)技术与实现(6)识文字,做分类:婚姻状态 、出生日期 、 户口地址 、 籍贯地址

    简历解析步骤(第二步)技术与实现(6)识文字,做分类:婚姻状态 .出生日期 . 户口地址 . 籍贯地址 继上篇文章理论: 简历解析,常见接收到的简历是图片或文档的方式,我们需要先将简历中的文字提取出来 ...

  8. 观点PK_倘若做不好AI,云服务商还能勇往直前吗?

    AI强大却不独立存在,如今已经成为人们普遍接受的理念之一. 在这个火热的时代,AI技术不是一个独立的产品,而是一种"基本生产力",它适用于大部分经济活动,可以让各行各业都产生&qu ...

  9. 劲爆!有人不用深度学习做强AI?道翰天琼认知智能机器人平台API接口大脑为您揭秘

    劲爆!有人不用深度学习做强AI?道翰天琼认知智能机器人平台API接口大脑为您揭秘 认知智能是计算机科学的一个分支科学,是智能科学发展的高级阶段,它以人类认知体系为基础,以模仿人类核心能力为目标,以信息 ...

最新文章

  1. 敏捷软件开发实践——估算与计划02
  2. manifest文件
  3. zabbix告警升级的迷惑
  4. python压平嵌套列表
  5. 剑指offer-week1
  6. 【学术相关】如何找到研究的突破点?
  7. python3学习笔记 雨痕_Python 3 学习笔记:数字和布尔
  8. mysql数据库查询优化建议_mysql数据库查询优化的24条建议
  9. python从菜鸟到高手 pdf 百度云_Python从菜鸟到高手(4):导入Python模块
  10. Vue中如何实现代码高亮功能?
  11. fastjson php,Fastjson 对象或数组转JSON
  12. 9个数中取最大值最小值速度问题
  13. Pyltp的安装使用笔记
  14. 有关计算机专业的对联,有趣的电脑对联(微软亚洲研究院自然语言计算组研发)...
  15. 华为手机长按图片无法下载
  16. 苹果原壁纸高清_ios14.2壁纸原图高清分享:苹果ios14.2壁纸高清无水印[多图]
  17. GenXus进行APP开发-全局颜色设计
  18. 分享积分兑换小程序开发制作功能介绍
  19. HTML中的bgcolor,background,与color的初步小节
  20. 计算机专业常用英语词汇1695

热门文章

  1. pci规划的三个原则_PCI规划应遵循什么原则? - 51学通信网络课堂 - 通信人值得信赖的在线交流学习平台 - Powered By EduSoho...
  2. 生产线平衡优化毕业论文【flexsim仿真】
  3. 华南产业集团发力数字经济,城链科技发布会成功召开
  4. MNE官网解读《Annotating continuous data》
  5. 使用GCD 转自 Posted by 唐巧
  6. c语言bb,bb平台,指针,c语言.doc
  7. leet198.打家劫舍
  8. Asp.NET Core+ABP框架+IdentityServer4+MySQL+Ext JS之部署到Linux
  9. 每日一课 | 数据分析的本质是什么?
  10. CAD学习记录01-快捷键