/// <summary>Execute the graph in the given blackboard.</summary> public override AIGraphResult Run(AIBlackboard blackboard) { // Save blackboard while executing. _blackboard = blackboard; // Get current state from blackboard. object state; if (!_blackboard.variables.TryGetValue("CurrentState" + GetInstanceID(), out state)) { return(null); } // Execute state. FSMStateNode currentState = state as FSMStateNode; currentState.Run(); // Get transition if any. FSMStateNode newState = currentState.GetTransition(); if (newState != null) { currentState.Exit(); _blackboard.variables["CurrentState" + GetInstanceID()] = newState; newState.Enter(); } // Nullify references to the blackboard. _blackboard = null; return(null); }
/// <summary>Unset the entry state node if it matches the given state.</summary> public void UnsetEntryState(FSMStateNode state) { // Only unset when the state passed is the same as the current one. if (state == _entryState) { _entryState = null; } }
/// <summary>Set a state node as the entry state.</summary> public void SetEntryState(FSMStateNode state) { // Unset previous root. if (_entryState != null) { _entryState.IsEntry = false; } // Set new root. _entryState = state; }
/// <summary>Get tint of the target node.</summary> public override Color GetTint() { // Check if there is an active game object. if (Selection.activeGameObject == null) { return(base.GetTint()); } // Try to get active state from FSM runner. AIGraphRunner runner = Selection.activeGameObject.GetComponent <AIGraphRunner>(); if (runner == null || _state == null) { return(base.GetTint()); } // Check if it is running. FSMGraph graph = _state.graph as FSMGraph; FSMStateNode current = runner.GetFromBlackboard("CurrentState" + graph.GetInstanceID()) as FSMStateNode; return(current == _state ? Color.yellow : base.GetTint()); }
/// <summary>Return the state to which we need to transition.</summary> public FSMStateNode GetTransition() { FSMStateNode output = null; // Check all exits. foreach (FSMConnection connection in exits) { // Make sure connection is valid. if (connection == null) { continue; } // Get state from connection, if not null return it. output = connection.GetState(); if (output != null) { return(output); } } return(null); }
/// <summary>Draw transition ports.</summary> protected virtual void OnTransitionsGUI() { _state = target as FSMStateNode; // Only work the GUI for the current exits and entries. int exitCount = _state.ExitsCount; int entryCount = _state.EntriesCount; // Check if we need to create new entry. _entry = target.GetInputPort("entry"); if (_entry == null) { _entry = target.AddInstanceInput(typeof(FSMConnection), Node.ConnectionType.Override, "entry"); } // If entry connection is not empty create new entry. if (_entry.Connection != null) { _state.AddEntryConnection(_entry.Connection); _entry.Disconnect(_entry.Connection); } // Check if we need to create new exit. _exit = target.GetOutputPort("exit"); if (_exit == null) { _exit = target.AddInstanceOutput(typeof(FSMConnection), Node.ConnectionType.Override, "exit"); } // If exit connection is not empty create new exit. if (_exit.Connection != null) { _state.AddExitConnection(_exit.Connection); _exit.Disconnect(_exit.Connection); } GUILayout.BeginHorizontal(); NodeEditorGUILayout.PortField(_entry, GUILayout.Width(50)); EditorGUILayout.Space(); NodeEditorGUILayout.PortField(_exit, GUILayout.Width(50)); GUILayout.EndHorizontal(); EditorGUILayout.Space(); for (int i = 0; i < entryCount; i++) { FSMConnection connection = _state.GetEntryConnection(i); NodePort port = target.GetInputPort(connection.PortName); NodePort connected = port.Connection; if (connected == null) { _state.RemoveEntryConnection(i); i--; entryCount--; } else { GUILayout.BeginHorizontal(); NodeEditorGUILayout.PortField(new GUIContent(), port, GUILayout.Width(-4)); EditorGUILayout.LabelField(string.Format("> {0}", connected.node.name)); GUILayout.EndHorizontal(); } } EditorGUILayout.Space(); for (int i = 0; i < exitCount; i++) { FSMConnection connection = _state.GetExitConnection(i); NodePort port = target.GetOutputPort(connection.PortName); NodePort connected = port.Connection; if (connected == null) { _state.RemoveExitConnection(i); i--; exitCount--; } else { GUILayout.BeginHorizontal(); EditorGUILayout.Space(); NodeEditorGUILayout.PortField(new GUIContent(), port, GUILayout.Width(50)); GUILayout.EndHorizontal(); } } }