文章目录
- Unity进阶--fsm状态机的使用笔记
- 第一种用基础的`if+播放实现动画控制
- switch--case实现状态机
- 使用状态机
Unity进阶–fsm状态机的使用笔记
第一种用基础的`if+播放实现动画控制
朴实无华,简单易懂,但是耦合性太差。
switch–case实现状态机
写对应的状态函数
再调用他们,合理,但存在调用问题。
使用状态机
-
编写状态基类
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(); }
-
编写状态机基类
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(); } } }
-
编写状态枚举
public enum PlayState { idle, run, wave }
-
编写几个状态
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); } } }
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); } } }
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); } } }
-
编写对应的角色控制状态机
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(); } }
-