Newer
Older
HierarchicalFSM-Unity3D / Assets / Scripts / NPC / FSM / FSM.cs
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class FSM : MonoBehaviour
  5. {
  6. [SerializeField] private State initialState;
  7. [SerializeField] private State currentState;
  8. [SerializeField] private NPCController controller;
  9. public NPCController Controller => controller;
  10. void Awake()
  11. {
  12. controller = GetComponent<NPCController>();
  13. }
  14. void Start()
  15. {
  16. currentState = initialState; //Sets a state
  17. }
  18. void Update()
  19. {
  20. if (currentState == null) return;
  21. ExecuteState(currentState);
  22. }
  23. private void ExecuteState(State state)
  24. {
  25. state.ExecuteActions(this);
  26. Transition triggeredTransition = state.GetTriggeredTransition(this);
  27. if (triggeredTransition != null)
  28. {
  29. ChangeState(triggeredTransition.TargetState());
  30. }
  31. else if (state.SubStates() != null && state.SubStates().Count > 0)
  32. {
  33. foreach (State substate in state.SubStates())
  34. {
  35. ExecuteState(substate);
  36. // Check for triggered transitions in the substate
  37. triggeredTransition = substate.GetTriggeredTransition(this);
  38. if (triggeredTransition != null)
  39. {
  40. // If a transition is triggered in the substate, change to the target state
  41. ChangeState(triggeredTransition.TargetState());
  42. return; // Exit after transitioning to avoid running further substates
  43. }
  44. }
  45. }
  46. }
  47. //Changes the current state to a new state
  48. public void ChangeState(State newState)
  49. {
  50. currentState?.ExitAction()?.Execute(this); //Executes the exit action of the current state
  51. currentState = newState; //Changes the state
  52. currentState?.Enter(this); //Executes entry action
  53. }
  54. //DEBUGING
  55. void OnGUI()
  56. {
  57. float yPosition = 10;
  58. float elementHeight = 20; // Height for each line
  59. float padding = 5;
  60. List<string> actions = new List<string>();
  61. foreach (Action action in currentState.GetActions())
  62. {
  63. actions.Add($"Action: {action.name}");
  64. }
  65. // Create a list to hold all the UI elements
  66. List<string> uiElements = new List<string> { $"State: {currentState.name}" };
  67. uiElements.AddRange(actions);
  68. // Define the GUIStyle
  69. GUIStyle style = new GUIStyle();
  70. style.fontSize = 14;
  71. for (int i = 0; i < uiElements.Count; i++)
  72. {
  73. if (i == 0)
  74. {
  75. style.normal.textColor = Color.green;
  76. }
  77. else
  78. {
  79. style.normal.textColor = Color.yellow;
  80. }
  81. // Create the rectangle for each line of text
  82. Rect rect = new Rect(10, yPosition, 300, elementHeight);
  83. // Display the label with the appropriate style
  84. GUI.Label(rect, uiElements[i], style);
  85. // Move the yPosition down for the next line
  86. yPosition += elementHeight + padding;
  87. }
  88. }
  89. }