文章目录
- Unity进阶--fsm状态机的使用笔记
- 第一种用基础的`if+播放实现动画控制
- switch--case实现状态机
- 使用状态机
Unity进阶–fsm状态机的使用笔记
第一种用基础的`if+播放实现动画控制
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yMi6hizN-1689928187185)(QQ%E6%88%AA%E5%9B%BE20230721104017.png)]](https://img-blog.csdnimg.cn/67f75670e28e4653ae2d95c10b8dba83.png)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vPPZXF2p-1689928187186)(QQ%E6%88%AA%E5%9B%BE20230721104429.png)]](https://img-blog.csdnimg.cn/b99cf0b095b44566b7ffd6ec3337d873.png)
朴实无华,简单易懂,但是耦合性太差。
switch–case实现状态机
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eC0QGMwr-1689928187187)(QQ%E6%88%AA%E5%9B%BE20230721112119.png)]](https://img-blog.csdnimg.cn/5086bf773acb4ed0bd35b84ed5ce31ce.png)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZckiCoY6-1689928187187)(QQ%E6%88%AA%E5%9B%BE20230721113102.png[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lw462qf8-1689928187417)(QQ%E6%88%AA%E5%9B%BE20230721105058.png)]]](https://img-blog.csdnimg.cn/5225d1d6024244daa9ede9199e62bc46.png)
写对应的状态函数
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W5WKaPi9-1689928187188)(QQ%E6%88%AA%E5%9B%BE20230721105520.png)]](https://img-blog.csdnimg.cn/8f2b8bab0bea4fc695c987fe1a70a270.png)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1gOBr8KL-1689928187188)(QQ%E6%88%AA%E5%9B%BE20230721105831.png)]](https://img-blog.csdnimg.cn/9ea78def106449a6bce1c43c8d9d8db3.png)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WFChp4VD-1689928187189)(QQ%E6%88%AA%E5%9B%BE20230721105958.png)]](https://img-blog.csdnimg.cn/51d55c594abe403fb68b846873aff936.png)
再调用他们,合理,但存在调用问题。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IiVtnGFI-1689928187190)(QQ%E6%88%AA%E5%9B%BE20230721105140.png)]](https://img-blog.csdnimg.cn/d0b88b056d4a46c0b94f9e1edff4f5a9.png)
使用状态机
-
编写状态基类
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XhC0DwX5-1689928187191)(QQ%E6%88%AA%E5%9B%BE20230721111443.png)]](https://img-blog.csdnimg.cn/0cd5c3c3d20e4332a867085703fb080a.png)
using System.Collections; using System.Collections.Generic; using UnityEngine; public abstract class FSMState { public int StateID; public MonoBehaviour Mono; public FSMManager FSMManager; public FSMState(int stateID, MonoBehaviour mono, FSMManager manager){ StateID = stateID; Mono = mono; FSMManager = manager; } public abstract void OnEnter(); public abstract void OnUpdate(); } -
编写状态机基类
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iWtDGkY3-1689928187191)(QQ%E6%88%AA%E5%9B%BE20230721112301.png)]](https://img-blog.csdnimg.cn/140f384d89dd411b90095c5ae1fe6065.png)
using System.Collections; using System.Collections.Generic; public class FSMManager { public List<FSMState> StateList = new List<FSMState>(); public int CurrentIndex = -1; public void ChangeState(int StateID){ CurrentIndex = StateID; StateList[CurrentIndex].OnEnter(); } public void Update() { if (CurrentIndex != -1){ StateList[CurrentIndex].OnUpdate(); } } } -
编写状态枚举
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4pLOXoXx-1689928187192)(QQ%E6%88%AA%E5%9B%BE20230721112119.png)]](https://img-blog.csdnimg.cn/4ed3e06714dc43bebe8eadbaa3ce89f1.png)
public enum PlayState { idle, run, wave } -
编写几个状态
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Mjlj2KBL-1689928187192)(QQ%E6%88%AA%E5%9B%BE20230721113412.png)]](https://img-blog.csdnimg.cn/0b5c938b6ebb426c9a1f976a0ec4e1eb.png)
using System.Collections; using System.Collections.Generic; using UnityEngine; public class RunState : FSMState { public RunState(int stateID, MonoBehaviour mono, FSMManager manager) : base(stateID, mono, manager) { } public override void OnEnter() { Mono.GetComponent<Animator>().SetFloat("Speed",5); } public override void OnUpdate() { float horizontal = Input.GetAxis("Horizontal"); float vertical = Input.GetAxis("Vertical"); Vector3 dir = new Vector3(horizontal, 0, vertical); if (dir != Vector3.zero){ Mono.transform.rotation = Quaternion.LookRotation(dir); Mono.transform.Translate(Vector3.forward * 5 * Time.deltaTime); } else { FSMManager.ChangeState((int)PlayState.idle); } } }![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GVXdl8Lg-1689928187192)(../AppData/Roaming/Typora/typora-user-images/image-20230721135226133.png)]](https://img-blog.csdnimg.cn/dc6c724f6a4b48dba8c036e30e9d44b5.png)
using System.Collections; using System.Collections.Generic; using UnityEngine; public class IdleState : FSMState { public IdleState(int stateID, MonoBehaviour mono, FSMManager manager) : base(stateID, mono, manager) { } public override void OnEnter() { Mono.GetComponent<Animator>().SetFloat("Speed",0); } public override void OnUpdate() { float horizontal = Input.GetAxis("Horizontal"); float vertical = Input.GetAxis("Vertical"); Vector3 dir = new Vector3(horizontal, 0, vertical); if (dir != Vector3.zero){ FSMManager.ChangeState((int)PlayState.run); } if (Input.GetKeyDown(KeyCode.Space)){ Debug.Log("按下空格"); FSMManager.ChangeState((int)PlayState.wave); } } }![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wbUcB6cR-1689928187193)(QQ%E6%88%AA%E5%9B%BE20230721113634.png)]](https://img-blog.csdnimg.cn/7ad81443250c423c9ae333c1f41381d5.png)
using System.Collections; using System.Collections.Generic; using UnityEngine; public class WaveState : FSMState { public WaveState(int stateID, MonoBehaviour mono, FSMManager manager) : base(stateID, mono, manager) { } public override void OnEnter() { Mono.GetComponent<Animator>().SetBool("Rest",true); } public override void OnUpdate() { if(!Mono.GetComponent<Animator>().GetCurrentAnimatorStateInfo(0).IsName("Rest")){ FSMManager.ChangeState((int)PlayState.idle); Mono.GetComponent<Animator>().SetBool("Rest",false); } } }-
编写对应的角色控制状态机
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QxsjWa1V-1689928187193)(../AppData/Roaming/Typora/typora-user-images/image-20230721135328692.png)]](https://img-blog.csdnimg.cn/9ebe00c5f6c241acaeffff0197099270.png)
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayControl : MonoBehaviour { private FSMManager fSMManager; // Start is called before the first frame update void Start() { fSMManager = new FSMManager(); IdleState idleState = new IdleState(0, this, fSMManager); RunState runState = new RunState(1, this, fSMManager); WaveState waveState = new WaveState(2, this, fSMManager); fSMManager.StateList.Add(idleState); fSMManager.StateList.Add(runState); fSMManager.StateList.Add(waveState); fSMManager.ChangeState((int)PlayState.idle); } // Update is called once per frame void Update() { fSMManager.Update(); } }
-



















