private void AddTransition(StateNode endState, Transition transition) { if (!connectedStates.Contains(endState.state)) { connectedStates.Add(endState.state); TransitionDataHolder t = ScriptableObject.CreateInstance <TransitionDataHolder>(); t.Init(RemoveTransition, RemoveTransitionFromInspector); t.TransitionsForState = new List <Transition>(); t.TransitionsForState.Add(transition); // If the other state transitions to this one, it needs to be two ways if (endState.connectedStates.Contains(state)) { t.TwoWayTransition = true; endState.stateTransitionInfo[state].TwoWayTransition = true; t.OtherWayTransition = endState.stateTransitionInfo[state]; endState.stateTransitionInfo[state].OtherWayTransition = t; endState.UpdateTriangleRotation(state); } stateTransitionInfo.Add(endState.state, t); } else { stateTransitionInfo[endState.state].TransitionsForState.Add(transition); } UpdateTriangleRotation(endState.state); }
/// <summary> /// Sets a state as the initial state in the state machine /// </summary> /// <param name="state"></param> private void OnSetStartState(StateNode state) { state.SetStyle(startStyle); if (startingState != null) { startingState.SetStyle(defaultStyle); } startingState = state; currentSM.CurrentState = state.NodeState; }
/// <summary> /// Creates a new transition /// </summary> public void CreateTransition(StateNode endState) { Transition transition = ScriptableObject.CreateInstance <Transition>(); transition.Init(endState.state); state.Transitions.Add(transition); transition.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(transition, state); AddTransition(endState, transition); }
/// <summary> /// Create a state that has transitions that are checked regardless of which state you are in /// </summary> /// <param name="mousePosition"></param> private void CreateAnyState(Vector2 mousePosition) { AnyState anyState = ScriptableObject.CreateInstance <AnyState>(); anyState.StateName = "Any State"; anyState.Rectangle = new Rect(mousePosition.x, mousePosition.y, nodeWidth, nodeHeight); anyStateNode = new StateNode(anyState, OnClickRemoveState, OnStartTransition, OnStateClick, OnStateChange, OnTransitionClicked, null); currentSM.AnyState = anyState; anyState.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(anyState, currentSM); }
/// <summary> /// When a node is changed, update the connector so the triangle updates /// </summary> /// <param name="node"></param> private void OnStateChange(StateNode state) { for (int i = 0; i < states.Count; i++) { for (int j = 0; j < states[i].NodeState.Transitions.Count; j++) { states[i].UpdateTriangleRotation(state.NodeState); } } if (anyStateNode != null) { anyStateNode.UpdateTriangleRotation(state.NodeState); } }
/// <summary> /// Loads data from the scriptable object /// </summary> private void LoadGraph() { states = new List <StateNode>(); if (currentSM != null) { // Load data Object[] assets = AssetDatabase.LoadAllAssetsAtPath(AssetDatabase.GetAssetPath(currentSM)); Dictionary <State, StateNode> stateToNodeRelation = new Dictionary <State, StateNode>(); foreach (Object obj in assets) { if (obj != null) { if (obj.GetType() == typeof(State)) { // Create all the states State state = (State)obj; StateNode newNode = new StateNode(state, OnClickRemoveState, OnStartTransition, OnStateClick, OnStateChange, OnTransitionClicked, OnSetStartState); states.Add(newNode); stateToNodeRelation.Add(state, newNode); if (state == currentSM.CurrentState) { startingState = newNode; } } } } if (currentSM.AnyState != null) { anyStateNode = new StateNode(currentSM.AnyState, OnClickRemoveState, OnStartTransition, OnStateClick, OnStateChange, OnTransitionClicked, null); for (int i = 0; i < currentSM.AnyState.Transitions.Count; i++) { anyStateNode.LoadTransition(stateToNodeRelation[currentSM.AnyState.Transitions[i].NextState], currentSM.AnyState.Transitions[i]); } } // Create all the transitions for (int i = 0; i < states.Count; i++) { for (int j = 0; j < states[i].NodeState.Transitions.Count; j++) { states[i].LoadTransition(stateToNodeRelation[states[i].NodeState.Transitions[j].NextState], states[i].NodeState.Transitions[j]); } } } }
/// <summary> /// Removed a node and all of its connections /// </summary> /// <param name="state"></param> private void OnClickRemoveState(StateNode state) { for (int i = 0; i < states.Count; i++) { if (states[i] != state) { for (int j = 0; j < states[i].NodeState.Transitions.Count; j++) { if (states[i].NodeState.Transitions[j].NextState == state.NodeState) { states[i].RemoveConnectedState(state.NodeState, states[i].NodeState.Transitions[j]); } } } } for (int i = 0; i < state.NodeState.Transitions.Count; i++) { DestroyImmediate(state.NodeState.Transitions[i], true); } states.Remove(state); DestroyImmediate(state.NodeState, true); }
/// <summary> /// Handles completing a transition connection /// </summary> /// <param name="state"></param> private void OnStateClick(StateNode state) { if (!creatingTransition) { Selection.activeObject = state.NodeState; subComponentEventOccured = true; } else { transitionEndState = state; if (transitionEndState != transitionStartState) { if (transitionEndState != anyStateNode) { CreateConnection(); ClearConnectionSelection(); } else { ClearConnectionSelection(); } } } }
/// <summary> /// Clears out the nodes for creating a connection /// </summary> private void ClearConnectionSelection() { transitionStartState = null; transitionEndState = null; }
/// <summary> /// Starts a transition connection /// </summary> /// <param name="state"></param> private void OnStartTransition(StateNode state) { transitionStartState = state; creatingTransition = true; }
public void LoadTransition(StateNode endState, Transition transition) { AddTransition(endState, transition); }