StateMachine1.WithDefault.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // Animancer // https://kybernetik.com.au/animancer // Copyright 2022 Kybernetik //
  2. using System;
  3. using UnityEngine;
  4. namespace Animancer.FSM
  5. {
  6. /// https://kybernetik.com.au/animancer/api/Animancer.FSM/StateMachine_1
  7. partial class StateMachine<TState>
  8. {
  9. /// <summary>A <see cref="StateMachine{TState}"/> with a <see cref="DefaultState"/>.</summary>
  10. /// <remarks>
  11. /// See <see cref="InitializeAfterDeserialize"/> if using this class in a serialized field.
  12. /// <para></para>
  13. /// Documentation: <see href="https://kybernetik.com.au/animancer/docs/manual/fsm/changing-states#default-states">Default States</see>
  14. /// </remarks>
  15. /// https://kybernetik.com.au/animancer/api/Animancer.FSM/WithDefault
  16. ///
  17. [Serializable]
  18. public class WithDefault : StateMachine<TState>
  19. {
  20. /************************************************************************************************************************/
  21. [SerializeField]
  22. private TState _DefaultState;
  23. /// <summary>The starting state and main state to return to when nothing else is active.</summary>
  24. /// <remarks>
  25. /// If the <see cref="CurrentState"/> is <c>null</c> when setting this value, it calls
  26. /// <see cref="ForceSetState(TState)"/> to enter the specified state immediately.
  27. /// <para></para>
  28. /// For a character, this would typically be their <em>Idle</em> state.
  29. /// </remarks>
  30. public TState DefaultState
  31. {
  32. get => _DefaultState;
  33. set
  34. {
  35. _DefaultState = value;
  36. if (_CurrentState == null && value != null)
  37. ForceSetState(value);
  38. }
  39. }
  40. /************************************************************************************************************************/
  41. /// <summary>Calls <see cref="ForceSetState(TState)"/> with the <see cref="DefaultState"/>.</summary>
  42. /// <remarks>This delegate is cached to avoid allocating garbage when used in Animancer Events.</remarks>
  43. public readonly Action ForceSetDefaultState;
  44. /************************************************************************************************************************/
  45. /// <summary>Creates a new <see cref="WithDefault"/>.</summary>
  46. public WithDefault()
  47. {
  48. // Silly C# doesn't allow instance delegates to be assigned using field initializers.
  49. ForceSetDefaultState = () => ForceSetState(_DefaultState);
  50. }
  51. /************************************************************************************************************************/
  52. /// <summary>Creates a new <see cref="WithDefault"/> and sets the <see cref="DefaultState"/>.</summary>
  53. public WithDefault(TState defaultState)
  54. : this()
  55. {
  56. _DefaultState = defaultState;
  57. ForceSetState(defaultState);
  58. }
  59. /************************************************************************************************************************/
  60. /// <inheritdoc/>
  61. public override void InitializeAfterDeserialize()
  62. {
  63. if (_CurrentState != null)
  64. {
  65. using (new StateChange<TState>(this, null, _CurrentState))
  66. _CurrentState.OnEnterState();
  67. }
  68. else if (_DefaultState != null)
  69. {
  70. using (new StateChange<TState>(this, null, CurrentState))
  71. {
  72. _CurrentState = _DefaultState;
  73. _CurrentState.OnEnterState();
  74. }
  75. }
  76. // Don't call the base method.
  77. }
  78. /************************************************************************************************************************/
  79. /// <summary>Attempts to enter the <see cref="DefaultState"/> and returns true if successful.</summary>
  80. /// <remarks>
  81. /// This method returns true immediately if the specified <see cref="DefaultState"/> is already the
  82. /// <see cref="CurrentState"/>. To allow directly re-entering the same state, use
  83. /// <see cref="TryResetDefaultState"/> instead.
  84. /// </remarks>
  85. public bool TrySetDefaultState() => TrySetState(DefaultState);
  86. /************************************************************************************************************************/
  87. /// <summary>Attempts to enter the <see cref="DefaultState"/> and returns true if successful.</summary>
  88. /// <remarks>
  89. /// This method does not check if the <see cref="DefaultState"/> is already the <see cref="CurrentState"/>.
  90. /// To do so, use <see cref="TrySetDefaultState"/> instead.
  91. /// </remarks>
  92. public bool TryResetDefaultState() => TryResetState(DefaultState);
  93. /************************************************************************************************************************/
  94. #if UNITY_EDITOR
  95. /************************************************************************************************************************/
  96. /// <inheritdoc/>
  97. public override int GUILineCount => 2;
  98. /************************************************************************************************************************/
  99. /// <inheritdoc/>
  100. public override void DoGUI(ref Rect area)
  101. {
  102. area.height = UnityEditor.EditorGUIUtility.singleLineHeight;
  103. UnityEditor.EditorGUI.BeginChangeCheck();
  104. var state = StateMachineUtilities.DoGenericField(area, "Default State", DefaultState);
  105. if (UnityEditor.EditorGUI.EndChangeCheck())
  106. DefaultState = state;
  107. StateMachineUtilities.NextVerticalArea(ref area);
  108. base.DoGUI(ref area);
  109. }
  110. /************************************************************************************************************************/
  111. #endif
  112. /************************************************************************************************************************/
  113. }
  114. }
  115. }