using System.Collections.Generic; using UnityEngine; namespace Code.StateMachine { public abstract class AbstractStateMachine where TStateMachineContext : new() { public TStateEnum CurrentState { get; protected set; } public BaseState CurrentBaseState { get; protected set; } private BaseState _previousBaseState; protected Dictionary> States = new(); public TStateEnum AllowedStates { get; set; } public TStateMachineContext StateMachineContext { get; protected set; } = new(); // protected virtual void Update() // { // CurrentBaseState.Tick(); // } // // protected void LateUpdate() // { // CurrentBaseState.LateTick(); // } // Костыли 2 шт. для флагового енама в шаблонах protected abstract bool CheckTransitionAllowed(TStateEnum nextState); protected abstract void ResetAllowedTransitions(); // TODO Если в EnterState вызывается ExitState, то будет гарантированная поломка public virtual AbstractStateMachine SwitchState(TStateEnum nextState) { if (!CheckTransitionAllowed(nextState)) { return null; } ResetAllowedTransitions(); _previousBaseState = CurrentBaseState; CurrentBaseState = States[nextState]; if (_previousBaseState != null) { _previousBaseState.OnExited += CurrentBaseState.EnterState; _previousBaseState.OnExited += FinishBaseStateTransition; _previousBaseState.ExitState(); } else { CurrentBaseState.EnterState(); } CurrentState = nextState; return this; } protected virtual void FinishBaseStateTransition() { _previousBaseState.OnExited -= CurrentBaseState.EnterState; _previousBaseState.OnExited -= FinishBaseStateTransition; _previousBaseState = null; } } }