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();
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)