有限状态机又称有限状态自动机(英语:finite-state automation,缩写:FSA),简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学计算模型。
简单说,它有三个特征:
状态机一般有两种实现方式:
当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
状态模式主要解决了两个问题:
状态模式和策略模式非常类似,状态模式与策略模式的区别
假如有一款游戏, 一个女英雄他有多种状态, 如站立、下蹲、跳跃、下斩等状态,按照常规的实现方式,我们可以用大量的if else来判断,或者switch case来实现, 但是这样做缺点很明显, 会存在大量bug并且代码不移维护和扩展。
此时我们就可以用状态机(状态模式)来实现,流程图如下:
来自大神 - 浅墨
//-------------------------------------------------------------------------------------
// TestHeroine.cs
//-------------------------------------------------------------------------------------
using UnityEngine;
using System.Collections;
public class TestHeroine : MonoBehaviour
{
private Heroine _heroine;
void Start ( )
{
_heroine = new Heroine();
}
void Update ( )
{
_heroine.Update();
}
}
//-------------------------------------------------------------------------------------
// Heroine.cs
//-------------------------------------------------------------------------------------
using UnityEngine;
using System.Collections;
public class Heroine
{
HeroineBaseState _state;
public Heroine()
{
_state = new StandingState(this);
}
public void SetHeroineState(HeroineBaseState newState)
{
_state = newState;
}
public void HandleInput()
{
}
public void Update()
{
_state.HandleInput();
}
}
//-------------------------------------------------------------------------------------
// HeroineBaseState.cs
//-------------------------------------------------------------------------------------
using UnityEngine;
using System.Collections;
public interface HeroineBaseState
{
void Update();
void HandleInput();
}
//-------------------------------------------------------------------------------------
// StandingState.cs
//-------------------------------------------------------------------------------------
using UnityEngine;
using System.Collections;
public class StandingState : HeroineBaseState
{
private Heroine _heroine;
public StandingState(Heroine heroine)
{
_heroine = heroine;
Debug.Log("------------------------Heroine in StandingState~!(进入站立状态!)");
}
public void Update()
{
}
public void HandleInput()
{
if (Input.GetKeyDown(KeyCode.UpArrow))
{
Debug.Log("get KeyCode.UpArrow!");
_heroine.SetHeroineState(new JumpingState(_heroine));
}
if (Input.GetKeyDown(KeyCode.DownArrow))
{
Debug.Log("get KeyCode.DownArrow!");
_heroine.SetHeroineState(new DuckingState(_heroine));
}
}
}
//-------------------------------------------------------------------------------------
// JumpState.cs
//-------------------------------------------------------------------------------------
using UnityEngine;
using System.Collections;
public class JumpingState : HeroineBaseState
{
private Heroine _heroine;
public JumpingState(Heroine heroine)
{
_heroine = heroine;
Debug.Log("------------------------Heroine in JumpingState~!(进入跳跃状态!)");
}
public void Update()
{
}
public void HandleInput()
{
if (Input.GetKeyDown(KeyCode.UpArrow))
{
Debug.Log("get GetKeyDown.UpArrow! but already in Jumping! return!(已经在跳跃状态中!)");
return;
}
if (Input.GetKeyDown(KeyCode.DownArrow))
{
Debug.Log("get KeyCode.DownArrow!");
_heroine.SetHeroineState(new DrivingState(_heroine));
}
}
}
//-------------------------------------------------------------------------------------
// DuckingState.cs
//-------------------------------------------------------------------------------------
using UnityEngine;
using System.Collections;
public class DuckingState : HeroineBaseState
{
private Heroine _heroine;
public DuckingState(Heroine heroine)
{
_heroine = heroine;
Debug.Log("------------------------Heroine in DuckingState~!(进入下蹲躲避状态!)");
}
public void Update()
{
}
public void HandleInput()
{
if (Input.GetKeyDown(KeyCode.DownArrow))
{
Debug.Log("已经在下蹲躲避状态中!");
return;
}
if (Input.GetKeyUp(KeyCode.UpArrow))
{
Debug.Log("get GetKeyUp.UpArrow!");
_heroine.SetHeroineState(new StandingState(_heroine));
}
}
}
//-------------------------------------------------------------------------------------
// DrivingState.cs
//-------------------------------------------------------------------------------------
using UnityEngine;
using System.Collections;
public class DrivingState : HeroineBaseState
{
private Heroine _heroine;
public DrivingState(Heroine heroine)
{
_heroine = heroine;
Debug.Log("------------------------Heroine in DrivingState~!(进入下斩状态!)");
}
public void Update()
{
}
public void HandleInput()
{
if (Input.GetKeyDown(KeyCode.UpArrow))
{
Debug.Log("get KeyCode.UpArrow!");
_heroine.SetHeroineState(new StandingState(_heroine));
}
}
}