StateKit

repository·master·Indexed 42 days ago

https://github.com/prime31/statekit

A C# state machine library providing two implementations: StateKit, a robust 'states as objects' system using SKState<T> and SKStateMachine<T> for complex logic, and StateKitLite, a lightweight, enum-driven FSM for simpler requirements.

Tokens
1K
Snippets
2
Records
3
Agent score
3%

What's inside StateKit

  1. How StateKit's 'states as objects' model works

    master

    StateKit uses a decoupled architecture where the state machine manages a collection of state objects.

    • Target Object: The object being controlled (the "focus") is passed to the SKStateMachine constructor and is accessible to all states.
    • State Lifecycle: Every state must implement begin (entry logic), update (per-frame logic), and end (exit logic).
    • State Management: The machine caches instances of states once they are used via changeState<T>(), preventing repeated allocations during transitions.
    • Registration: You must explicitly add state instances to the machine using addState() before they can be transitioned to.
  2. Use StateKit for object-oriented state machines

    master

    StateKit implements a "states as objects" system where each state is a separate class. This allows you to separate state logic from the target object (e.g., a Player or NPC) while maintaining access to it.

    To use StateKit:

    1. Create states by inheriting from SKState<T>, where T is the type of your target object.
    2. Implement three required methods in each state: begin, update, and end.
    3. Initialize the machine using new SKStateMachine<T>(targetObject, initialState).
    4. Register additional states using addState(new StateClass()).
    5. Drive the machine by calling update(deltaTime) (typically in a game loop like Update or FixedUpdate).
    6. Transition states using changeState<TState>(), which automatically handles instantiation and caching.
    // create a state machine that will work with an object of type SomeClass as the focus with an initial state of PatrollingState
    var machine = new SKStateMachine<SomeClass>( someClass, new PatrollingState() );
    
    // we can now add any additional states
    _machine.addState( new AttackState() );
    _machine.addState( new ChaseState() );
    
    // this method would typically be called in an Update/FixedUpdate of an object
    machine.update( Time.deltaTime );
    
    // change states. the state machine will automatically create and cache an instance of the class (in this case ChasingState)
    machine.changeState<ChasingState>();
  3. Use StateKitLite for enum-based finite state machines

    master

    StateKitLite is a simplified, single-class FSM driven by an enum. It is ideal for simpler logic where you want to define states via method naming conventions rather than separate classes.

    To use StateKitLite:

    1. Subclass StateKitLite<TEnum>, where TEnum is your state enumeration.
    2. Define state logic using the naming convention: {EnumMember}_{LifecycleMethod}().
      • {EnumMember}_Enter()
      • {EnumMember}_Tick()
      • {EnumMember}_Exit()
    3. Set the initialState property in Awake or Start.
    4. Change states by assigning a new value to the currentState property.

    Important Rules for Subclassing:

    • If you implement Awake, you must call base.Awake().
    • If you implement Update, you must call base.Update().
    • You must set initialState in either Awake or Start.
    enum SomeEnum
    {
    	Walking,
    	Idle
    }
    
    public class YourClass : StateKitLite<SomeEnum>()
    {
    	void Start()
    	{
    		initialState = SomeEnum.Idle;
    	}
    
    	void Walking_Enter() {}
    	void Walking_Tick() {}
    	void Walking_Exit() {}
    
    	void Idle_Enter() {}
    	void Idle_Tick() {}
    	void Idle_Exit() {}
    }