using System; using System.Collections.Generic; using UnityEngine; public abstract class State { public StateHandler Owner { get; private set; } public void Initialize(StateHandler owner) { Owner = owner; OnInitialize(); } protected virtual void OnInitialize() { } public virtual void Enter() { } public virtual void Excute() { } public virtual void Exit() { } } public abstract class StateHandler : MonoBehaviour { public T Excutor { get; private set; } Dictionary> globalStates = new(); Dictionary> states = new(); public State CurrentGlobalState { get; private set;} public State CurrentState { get; private set; } public void Initialize(T excutor) { Excutor = excutor; OnInitialize(); foreach (var state in globalStates.Values) { state.Initialize(this); } foreach (var state in states.Values) { state.Initialize(this); } if(CurrentGlobalState != null) { CurrentGlobalState.Enter(); } if(CurrentState != null) { CurrentState.Enter(); } } protected abstract void OnInitialize(); private void Update() { CurrentGlobalState?.Excute(); CurrentState?.Excute(); } public void AddGlobalState() where TState : State { var state = Activator.CreateInstance(); globalStates.Add(typeof(TState), state); if(CurrentGlobalState == null) { CurrentGlobalState = state; } } public void AddState() where TState : State { var state = Activator.CreateInstance(); states.Add(typeof(TState), state); if(CurrentState == null) { CurrentState = state; } } public bool TryGetGlobalState(Type type, out State state) { return globalStates.TryGetValue(type, out state); } public bool TryGetGlobalState(out TState state) where TState : State { state = null; if(TryGetGlobalState(typeof(TState), out var baseState)) state = baseState as TState; return state != null; } public bool TryGetState(Type type, out State state) { return states.TryGetValue(type, out state); } public bool TryGetState(out TState state) where TState : State { state = null; if(TryGetState(typeof(TState), out var baseState)) state = baseState as TState; return state != null; } public void ChangeGlobalState() where TState : State { if(CurrentGlobalState != null) { CurrentGlobalState.Exit(); } CurrentGlobalState = globalStates[typeof(TState)]; if(CurrentGlobalState != null) { CurrentGlobalState.Enter(); } } public void ChangeState() where TState : State { if(CurrentState != null) { CurrentState.Exit(); } CurrentState = states[typeof(TState)]; if(CurrentState != null) { CurrentState.Enter(); } } }