StateMachine1.WithDefault.cs 6.5 KB

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