namespace UOP1.StateMachine { public class StateTransition : IStateComponent { private State _targetState; private StateCondition[] _conditions; private int[] _resultGroups; private bool[] _results; internal StateTransition() { } public StateTransition(State targetState, StateCondition[] conditions, int[] resultGroups = null) { Init(targetState, conditions, resultGroups); } internal void Init(State targetState, StateCondition[] conditions, int[] resultGroups = null) { _targetState = targetState; _conditions = conditions; _resultGroups = resultGroups != null && resultGroups.Length > 0 ? resultGroups : new int[1]; _results = new bool[_resultGroups.Length]; } /// /// Checks wether the conditions to transition to the target state are met. /// /// Returns the state to transition to. Null if the conditions aren't met. /// True if the conditions are met. public bool TryGetTransiton(out State state) { state = ShouldTransition() ? _targetState : null; return state != null; } public void OnStateEnter() { for (int i = 0; i < _conditions.Length; i++) _conditions[i]._condition.OnStateEnter(); } public void OnStateExit() { for (int i = 0; i < _conditions.Length; i++) _conditions[i]._condition.OnStateExit(); } private bool ShouldTransition() { #if UNITY_EDITOR _targetState._stateMachine._debugger.TransitionEvaluationBegin(_targetState._originSO.name); #endif int count = _resultGroups.Length; for (int i = 0, idx = 0; i < count && idx < _conditions.Length; i++) for (int j = 0; j < _resultGroups[i]; j++, idx++) _results[i] = j == 0 ? _conditions[idx].IsMet() : _results[i] && _conditions[idx].IsMet(); bool ret = false; for (int i = 0; i < count && !ret; i++) ret = ret || _results[i]; #if UNITY_EDITOR _targetState._stateMachine._debugger.TransitionEvaluationEnd(ret, _targetState._actions); #endif return ret; } internal void ClearConditionsCache() { for (int i = 0; i < _conditions.Length; i++) _conditions[i]._condition.ClearStatementCache(); } } }