Skip to content
This repository has been archived by the owner on Dec 10, 2022. It is now read-only.

codewriter-packages/Morpeh.StateMachine

Repository files navigation

⚠️ REPO ARCHIVED ⚠️

Problems with this implementation:

  • no way to check the current state of entity
  • unreliable state switching mechanism

Morpeh.StateMachine Github license Unity 2020.1 GitHub package.json version

State Machine for Morpeh ECS

How to use?

using System;
using Morpeh;

// ==========================
// === Declare components ===
// ==========================

[Serializable]
public struct UnitComponent : IComponent { }

public static class UnitFsmEvents {
    [Serializable]
    public struct TargetFound : IComponent { public Entity target; }
    
    [Serializable]
    public struct TargetLost : IComponent { }
}

public static class UnitFsmStates {
    [Serializable]
    public struct Idle : IComponent { }

    [Serializable]
    public struct FollowTarget : IComponent { public Entity target; }
}

// ============================
// === Declare StateMachine ===
// ============================

public class UniBehaviourSystem : UpdateSystem {
    private Fsm fsm;

    public override void OnAwake() {
        this.fsm = new Fsm(World, Filter.With<UnitComponent>());

        this.fsm.AtState<UnitFsmStates.Idle>()
            .Transition((ref UnitFsmEvents.TargetFound evt) => new UnitFsmStates.FollowTarget {
                target = evt.target,
            });

        this.fsm.AtState<UnitFsmStates.FollowTarget>()
            .OnEnter(entity => Debug.Log("Enter FollowTarget state"))
            .OnExit(entity => Debug.Log("Exit FollowTarget state"))
            .Transition((ref UnitFsmEvents.TargetLost evt) => new UnitFsmStates.Idle());
    }

    public override void OnUpdate(float deltaTime) {
        this.fsm.Execute();
    }
}

// ===============================================
// === Write systems with logic for each state ===
// ===============================================

public class UnitIdleSystem : UpdateSystem {
    private Filter unitsFilter;

    public override void OnAwake() {
        this.unitsFilter = Filter.With<UnitComponent>().With<UnitFsmStates.Idle>();
    }

    public override void OnUpdate(float deltaTime) {
        foreach (var entity in this.unitsFilter) {
            if (TryGetTarget(out var target)) {
                entity.AddComponent<UnitFsmEvents.TargetFound>();
            }
        }
    }

    private bool TryGetTarget(out Entity target) { /* ... */ }
}

public class UnitFollowTargetSystem : UpdateSystem {
    private Filter unitsFilter;

    public override void OnAwake() {
        this.unitsFilter = Filter.With<UnitComponent>().With<UnitFsmStates.FollowTarget>();
    }

    public override void OnUpdate(float deltaTime) {
        foreach (var entity in this.unitsFilter) {
            ref var followTargetState = ref entity.GetComponent<UnitFsmStates.FollowTarget>();

            if (followTargetState.target.IsNullOrDisposed()) {
                entity.AddComponent<UnitFsmEvents.TargetLost>();
            }
        }
    }
}

// ======================================
// === Create Unit with initial state ===
// ======================================

public class UnitSpawnSystem : Initializer
{
    public override void OnAwake()
    {
        var entity = World.CreateEntity();
        entity.AddComponent<UnitComponent>();
        entity.AddComponent<UnitFsmStates.Idle>();
    }
}

License

Morpeh.StateMachine is MIT licensed.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Languages