Unity3d的一个状态机实现

1.这是State的实现:

public class State
{
     private readonly List<StateTransition> transitions = new List<StateTransition>();
 
     protected Action StartAction { get ; set ; }
     protected Action StopAction { get ; set ; }
     protected Action UpdateAction { get ; set ; }
 
     protected internal bool IsStarted { get ; set ; }
 
     protected internal void Start()
     {
         if (!IsStarted && StartAction != null )
         {
             StartAction();
             IsStarted = true ;
         }
     }
 
     protected internal void Update()
     {
         if (IsStarted && UpdateAction != null )
         {
             UpdateAction();
         }
     }
 
     protected internal void Stop()
     {
         if (IsStarted && StopAction != null )
         {
             StopAction();
             IsStarted = false ;
         }
     }
 
     public State AddStartAction(Action startAction)
     {
         StartAction += startAction;
         return this ;
     }
 
     public State AddUpdateAction(Action updateAction)
     {
         UpdateAction += updateAction;
         return this ;
     }
 
     public State AddStopAction(Action stopAction)
     {
         StopAction += stopAction;
         return this ;
     }
 
     public State AddTransition(Predicate<State> condition, State nextState)
     {
         transitions.Add( new StateTransition(condition, nextState));
         return this ;
     }
 
     public bool CanGoToNextState( out State nextState)
     {
         for ( int i = 0; i < transitions.Count; i++)
         {
             if (transitions[i].Condition( this ))
             {
                 nextState = transitions[i].NextState;
                 return true ;
             }
         }
 
         nextState = null ;
         return false ;
     }
 
     public bool HasNextState()
     {
         return transitions.Count != 0;
     }
}

public class StateTransition{

public Predicate<State> Condition;

public State NextState;

public StateTransition(Predicate<State> condition,State nextState){

Condition=condition;

NextState=nextState;

}

2.这是StateMachine的实现:

public class StateMachine : State
{
     private readonly State initialState;
     public State CurrenState { get ; private set ; }
 
     public StateMachine(State initialState)
     {
         this .initialState = initialState;
         StartAction = Start;
         UpdateAction = Update;
         StopAction = Stop;
     }
 
     public new void Start()
     {
         if (IsStarted)
         {
             return ;
         }
 
         CurrenState = initialState;
         CurrenState.Start();
         IsStarted = true ;
     }
 
     public new void Update()
     {
         if (CurrenState == null )
         {
             return ;
         }
 
         if (!CurrenState.IsStarted)
         {
             CurrenState.Start();
         }
 
         CurrenState.Update();
 
         State nextState;
         while (CurrenState.CanGoToNextState( out nextState))
         {
             if (CurrenState.IsStarted)
             {
                 CurrenState.Stop();
             }
 
             CurrenState = nextState;
 
             if (!CurrenState.IsStarted)
             {
                 CurrenState.Start();
             }
 
             CurrenState.Update();
         }
 
         if (!CurrenState.HasNextState())
         {
             Stop();
         }
     }
 
     public new void Stop()
     {
         if (CurrenState == null )
         {
             return ;
         }
 
         if (CurrenState.IsStarted)
         {
             CurrenState.Stop();
         }
 
         CurrenState = null ;
     }
}


Test:

public class Test : MonoBehaviour
{
     private StateMachine stateMachine;
 
     private State firstState = new State();
     private State secondState = new CustomState();
     private State finishState = new State();
 
     // Use this for initialization
     void Start ()
     {
         var initChild = new State()
             .AddStartAction(() => Debug.Log(Time.frameCount + " childInit Start" ))
             .AddUpdateAction(() => Debug.Log(Time.frameCount + " childInit Update" ))
             .AddStopAction(() => Debug.Log(Time.frameCount + " childInit Stop" ));
         var childStateMachine = new StateMachine(initChild);
         stateMachine = new StateMachine(firstState);
 
         firstState
             .AddStartAction(() => Debug.Log(Time.frameCount + " 1 Start" ))
             .AddUpdateAction(() => Debug.Log(Time.frameCount + " 1 Update" ))
             .AddStopAction(() => Debug.Log(Time.frameCount + " 1 Stop" ))
             .AddTransition(
                 state => Time.frameCount == 5,
                 secondState)
             .AddTransition(
                 state => Time.frameCount == 15,
                 secondState);
 
         secondState
             .AddTransition(
                 state => Time.frameCount == 10,
                 firstState)
             .AddTransition(
                 state => Input.GetKey(KeyCode.Q),
                 childStateMachine);
 
         childStateMachine
             .AddTransition(s => Input.GetKey(KeyCode.Y), finishState);
 
         finishState
             .AddStartAction(() => Debug.Log(Time.frameCount + " finish Start" ));
 
         stateMachine.Start();
     }
 
     void Update()
     {
         stateMachine.Update();
     }
}
 
public class CustomState : State
{
     public CustomState()
     {
         StartAction = CustomStart;
         UpdateAction = CustomUpdate;
         StopAction = CustomStop;
     }
 
     public void CustomStart()
     {
         Debug.Log(Time.frameCount + " custom start" );
     }
 
     public void CustomUpdate()
     {
         Debug.Log(Time.frameCount + " custom update" );
     }
 
     public void CustomStop()
     {
         Debug.Log(Time.frameCount + " custom stop" );
     }
}


猜你喜欢

转载自blog.csdn.net/qq_31967569/article/details/81063868