// Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2023 Kybernetik // using System; using UnityEngine; namespace Animancer.FSM { /// https://kybernetik.com.au/animancer/api/Animancer.FSM/StateMachine_1 partial class StateMachine { /// A with a . /// /// See if using this class in a serialized field. /// /// Documentation: Default States /// /// https://kybernetik.com.au/animancer/api/Animancer.FSM/WithDefault /// [Serializable] public class WithDefault : StateMachine { /************************************************************************************************************************/ [SerializeField] private TState _DefaultState; /// The starting state and main state to return to when nothing else is active. /// /// If the is null when setting this value, it calls /// to enter the specified state immediately. /// /// For a character, this would typically be their Idle state. /// public TState DefaultState { get => _DefaultState; set { _DefaultState = value; if (_CurrentState == null && value != null) ForceSetState(value); } } /************************************************************************************************************************/ /// Calls with the . /// This delegate is cached to avoid allocating garbage when used in Animancer Events. public readonly Action ForceSetDefaultState; /************************************************************************************************************************/ /// Creates a new . public WithDefault() { // Silly C# doesn't allow instance delegates to be assigned using field initializers. ForceSetDefaultState = () => ForceSetState(_DefaultState); } /************************************************************************************************************************/ /// Creates a new and sets the . public WithDefault(TState defaultState) : this() { _DefaultState = defaultState; ForceSetState(defaultState); } /************************************************************************************************************************/ /// public override void InitializeAfterDeserialize() { if (_CurrentState != null) { using (new StateChange(this, null, _CurrentState)) _CurrentState.OnEnterState(); } else if (_DefaultState != null) { using (new StateChange(this, null, CurrentState)) { _CurrentState = _DefaultState; _CurrentState.OnEnterState(); } } // Don't call the base method. } /************************************************************************************************************************/ /// Attempts to enter the and returns true if successful. /// /// This method returns true immediately if the specified is already the /// . To allow directly re-entering the same state, use /// instead. /// public bool TrySetDefaultState() => TrySetState(DefaultState); /************************************************************************************************************************/ /// Attempts to enter the and returns true if successful. /// /// This method does not check if the is already the . /// To do so, use instead. /// public bool TryResetDefaultState() => TryResetState(DefaultState); /************************************************************************************************************************/ #if UNITY_EDITOR /************************************************************************************************************************/ /// public override int GUILineCount => 2; /************************************************************************************************************************/ /// public override void DoGUI(ref Rect area) { area.height = UnityEditor.EditorGUIUtility.singleLineHeight; UnityEditor.EditorGUI.BeginChangeCheck(); var state = StateMachineUtilities.DoGenericField(area, "Default State", DefaultState); if (UnityEditor.EditorGUI.EndChangeCheck()) DefaultState = state; StateMachineUtilities.NextVerticalArea(ref area); base.DoGUI(ref area); } /************************************************************************************************************************/ #endif /************************************************************************************************************************/ } } }