// 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_2 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 new class WithDefault : StateMachine { /************************************************************************************************************************/ [SerializeField] private TKey _DefaultKey; /// 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 TKey DefaultKey { get => _DefaultKey; set { _DefaultKey = 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(_DefaultKey); } /************************************************************************************************************************/ /// Creates a new and sets the . public WithDefault(TKey defaultKey) : this() { _DefaultKey = defaultKey; ForceSetState(defaultKey); } /************************************************************************************************************************/ /// public override void InitializeAfterDeserialize() { if (CurrentState != null) { using (new KeyChange(this, default, _DefaultKey)) using (new StateChange(this, null, CurrentState)) CurrentState.OnEnterState(); } else { ForceSetState(_DefaultKey); } // 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 TState TrySetDefaultState() => TrySetState(_DefaultKey); /************************************************************************************************************************/ /// 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 TState TryResetDefaultState() => TryResetState(_DefaultKey); /************************************************************************************************************************/ #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 Key", DefaultKey); if (UnityEditor.EditorGUI.EndChangeCheck()) DefaultKey = state; StateMachineUtilities.NextVerticalArea(ref area); base.DoGUI(ref area); } /************************************************************************************************************************/ #endif /************************************************************************************************************************/ } } }