/// <summary> /// Undocumented Unity callback to draw a button in the window tab. /// Draws the selection lock button. /// <param name="rect">The button rect.</param> /// </summary> void ShowButton(Rect rect) { // Create style? if (s_Styles == null) { s_Styles = new BehaviourWindow.Styles(); } // Shows the lock icon if (GUI.Toggle(rect, m_Lock, GUIContent.none, s_Styles.lockButton) != m_Lock) { // Ping game object ParentBehaviour parent = activeParent; if (parent != null) { EditorGUIUtility.PingObject(parent.gameObject); } // Toggle lock m_Lock = !m_Lock; // The selection is not locked? if (!m_Lock) { // Update selection OnSelectionChange(); } } }
/// <summary> /// Paste the state in StateUtility.stateToPaste in the supplied fsm. /// <param name="parent">The target parent.</param> /// </summary> public static void PasteStates(ParentBehaviour parent) { if (parent != null) { CloneStates(parent.gameObject, statesToPaste, parent); } }
/// <summary> /// Adds a state to the supplied parent. /// Automatically handles undo. /// <param name="parent">The ParentBehaviour to add the new state.</param> /// <param name="type">The new state type.</param> /// <returns>The new created state.<returns> /// </summary> public static InternalStateBehaviour AddState(ParentBehaviour parent, System.Type type) { // Validate parameters if (type != null && parent != null) { // Create and register undo #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2 Undo.RegisterSceneUndo("Create State (" + type.Name + ")"); #endif InternalStateBehaviour newState = parent.AddState(type); if (newState != null) { // Register undo #if !UNITY_4_0_0 && !UNITY_4_1 && !UNITY_4_2 Undo.RegisterCreatedObjectUndo(newState, "Create State (" + type.Name + ")"); #endif // The parent is a FSM? var fsm = parent as InternalStateMachine; if (fsm != null) { // The newState is an AnyState? if (newState is InternalAnyState) { // The fsm already has an AnyState? if (fsm.anyState != null) { // Destroy the curren anyState StateUtility.Destroy(fsm.anyState); } // Add the new anyState fsm.anyState = newState as InternalAnyState; } // The start state is null? else if (fsm.startState == null) { // Set the new state as the start state fsm.startState = newState; EditorUtility.SetDirty(fsm); } } // Sets dirty flag EditorUtility.SetDirty(parent.gameObject); } return(newState); } return(null); }
/// <summary> /// A Unity callback called whenever the selection has changed. /// Updates the active parent if necessary. /// </summary> void OnSelectionChange() { // Selection option is unlocked or the active parent is null? if (!m_Lock || s_ActiveParentID == 0) { // Get the active game object var selectedGameObject = Selection.activeObject as GameObject; // Get the first ParentBehaviour in the selectedGameObject. ParentBehaviour selectedParent = selectedGameObject != null?selectedGameObject.GetComponent <ParentBehaviour>() : null; // There is no activeParent or the activeParent game object is not the active game object? if (activeParent == null || (selectedGameObject != null && selectedGameObject != activeParent.gameObject)) { activeParent = selectedParent; } } Repaint(); }
/// <summary> /// Paste the state in StateUtility.stateToPaste in the supplied fsm. /// <param name="gameObject">The target gameObject.</param> /// <param name="originalStates">The original states.</param> /// <param name="parent">Optionally parent for the cloned states.</param> /// </summary> public static void CloneStates(GameObject gameObject, InternalStateBehaviour[] originalStates, ParentBehaviour parent) { if (gameObject != null && originalStates != null && originalStates.Length > 0) { var orginalClone = new Dictionary <InternalStateBehaviour, InternalStateBehaviour>(); var originalFsm = parent != null ? originalStates[0].parent as InternalStateMachine : null; var newFsm = parent as InternalStateMachine; InternalStateBehaviour startState = null, concurrentState = null; InternalAnyState anyState = null; // Copy blackboard data? var newBlackboard = gameObject.GetComponent <InternalBlackboard>(); if (newBlackboard == null) { // Get the original blackboard InternalBlackboard originalBlackboard = originalStates[0].GetComponent <InternalBlackboard>(); #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2 Undo.RegisterSceneUndo("Paste State"); // Create the new blacbkoard newBlackboard = gameObject.AddComponent(originalBlackboard.GetType()) as InternalBlackboard; #else // Create the new blacbkoard newBlackboard = gameObject.AddComponent(originalBlackboard.GetType()) as InternalBlackboard; if (newBlackboard != null) { Undo.RegisterCreatedObjectUndo(newBlackboard, "Paste State"); } #endif // Copy serialized values EditorUtility.CopySerialized(originalBlackboard, newBlackboard); } foreach (InternalStateBehaviour state in originalStates) { // Don't clone AnyState in StateMachines if (state != null && (newFsm == null || !(state is InternalAnyState) || newFsm.anyState == null)) { #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2 Undo.RegisterSceneUndo("Paste State"); // Create a new state var newState = gameObject.AddComponent(state.GetType()) as InternalStateBehaviour; #else // Create a new state var newState = gameObject.AddComponent(state.GetType()) as InternalStateBehaviour; if (newState != null) { Undo.RegisterCreatedObjectUndo(newState, "Paste State"); } #endif if (newState != null) { // Store state orginalClone.Add(state, newState); // Copy serialized values EditorUtility.CopySerialized(state, newState); // Update blackboard if (state.gameObject != newState.gameObject) { var serialObj = new SerializedObject(newState); serialObj.FindProperty("m_Blackboard").objectReferenceValue = newBlackboard; serialObj.ApplyModifiedProperties(); serialObj.Dispose(); } // Update the AnyState, StartState and ConcurrentState if (newState is InternalStateMachine) { var fsm = newState as InternalStateMachine; fsm.startState = null; fsm.concurrentState = null; fsm.anyState = null; } EditorUtility.SetDirty(newState); // Set new parent if (parent != null) { newState.parent = parent; // Update position if (parent == state.parent) { newState.position += new Vector2(20f, 20f); } } else { newState.parent = null; } // Saves state and sets dirty flag INodeOwner nodeOwner = newState as INodeOwner; if (nodeOwner != null) { nodeOwner.LoadNodes(); StateUtility.SetDirty(nodeOwner); } else { EditorUtility.SetDirty(newState); } // Try to get the StartState, AnyState and ConcurrentState if (originalFsm != null) { if (originalFsm.startState == state) { startState = newState; } if (anyState == null) { anyState = newState as InternalAnyState; } if (originalFsm.concurrentState == state) { concurrentState = newState; } } } } } // Set StartState, AnyState and ConcurrentState if (newFsm != null) { if (newFsm.startState == null) { newFsm.startState = startState; } if (newFsm.anyState == null) { newFsm.anyState = anyState; } if (newFsm.concurrentState == null) { newFsm.concurrentState = concurrentState; } EditorUtility.SetDirty(newFsm); } // Try to update the transitions' destination foreach (KeyValuePair <InternalStateBehaviour, InternalStateBehaviour> pair in orginalClone) { InternalStateBehaviour state = pair.Key; InternalStateBehaviour newState = pair.Value; // Update the newState transition for (int i = 0; i < newState.transitions.Length && i < state.transitions.Length; i++) { // The original destination is valid? if (state.transitions[i].destination != null && orginalClone.ContainsKey(state.transitions[i].destination)) { newState.transitions[i].destination = orginalClone[state.transitions[i].destination]; } } if (newState is ParentBehaviour) { var stateAsParent = state as ParentBehaviour; // Removes the newState from the children state to avoid an infinite loop List <InternalStateBehaviour> children = stateAsParent.states; if (children.Contains(newState)) { children.Remove(newState); } StateUtility.CloneStates(newState.gameObject, children.ToArray(), newState as ParentBehaviour); } EditorUtility.SetDirty(newState); } EditorUtility.SetDirty(gameObject); } }
/// <summary> /// Saves the last parent. /// </summary> void SaveLastParent () { m_LastParent = m_Parent; }
/// <summary> /// Adds a state to the supplied parent. /// Automatically handles undo. /// <param name="parent">The ParentBehaviour to add the new state.</param> /// <param name="type">The new state type.</param> /// <returns>The new created state.<returns> /// </summary> public static InternalStateBehaviour AddState (ParentBehaviour parent, System.Type type) { // Validate parameters if (type != null && parent != null) { // Create and register undo #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2 Undo.RegisterSceneUndo("Create State (" + type.Name + ")"); #endif InternalStateBehaviour newState = parent.AddState(type); if (newState != null) { // Register undo #if !UNITY_4_0_0 && !UNITY_4_1 && !UNITY_4_2 Undo.RegisterCreatedObjectUndo(newState, "Create State (" + type.Name + ")"); #endif // The parent is a FSM? var fsm = parent as InternalStateMachine; if (fsm != null) { // The newState is an AnyState? if (newState is InternalAnyState) { // The fsm already has an AnyState? if (fsm.anyState != null) // Destroy the curren anyState StateUtility.Destroy(fsm.anyState); // Add the new anyState fsm.anyState = newState as InternalAnyState; } // The start state is null? else if (fsm.startState == null) { // Set the new state as the start state fsm.startState = newState; EditorUtility.SetDirty(fsm); } } // Sets dirty flag EditorUtility.SetDirty(parent.gameObject); } return newState; } return null; }
/// <summary> /// Paste the state in StateUtility.stateToPaste in the supplied fsm. /// <param name="gameObject">The target gameObject.</param> /// <param name="originalStates">The original states.</param> /// <param name="parent">Optionally parent for the cloned states.</param> /// </summary> public static void CloneStates (GameObject gameObject, InternalStateBehaviour[] originalStates, ParentBehaviour parent) { if (gameObject != null && originalStates != null && originalStates.Length > 0) { var orginalClone = new Dictionary<InternalStateBehaviour, InternalStateBehaviour>(); var originalFsm = parent != null ? originalStates[0].parent as InternalStateMachine : null; var newFsm = parent as InternalStateMachine; InternalStateBehaviour startState = null, concurrentState = null; InternalAnyState anyState = null; // Copy blackboard data? var newBlackboard = gameObject.GetComponent<InternalBlackboard>(); if (newBlackboard == null) { // Get the original blackboard InternalBlackboard originalBlackboard = originalStates[0].GetComponent<InternalBlackboard>(); #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2 Undo.RegisterSceneUndo("Paste State"); // Create the new blacbkoard newBlackboard = gameObject.AddComponent(originalBlackboard.GetType()) as InternalBlackboard; #else // Create the new blacbkoard newBlackboard = gameObject.AddComponent(originalBlackboard.GetType()) as InternalBlackboard; if (newBlackboard != null) Undo.RegisterCreatedObjectUndo(newBlackboard, "Paste State"); #endif // Copy serialized values EditorUtility.CopySerialized(originalBlackboard, newBlackboard); } foreach (InternalStateBehaviour state in originalStates) { // Don't clone AnyState in StateMachines if (state != null && (newFsm == null || !(state is InternalAnyState) || newFsm.anyState == null)) { #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2 Undo.RegisterSceneUndo("Paste State"); // Create a new state var newState = gameObject.AddComponent(state.GetType()) as InternalStateBehaviour; #else // Create a new state var newState = gameObject.AddComponent(state.GetType()) as InternalStateBehaviour; if (newState != null) Undo.RegisterCreatedObjectUndo(newState, "Paste State"); #endif if (newState != null) { // Store state orginalClone.Add(state, newState); // Copy serialized values EditorUtility.CopySerialized(state, newState); // Update blackboard if (state.gameObject != newState.gameObject) { var serialObj = new SerializedObject(newState); serialObj.FindProperty("m_Blackboard").objectReferenceValue = newBlackboard; serialObj.ApplyModifiedProperties(); serialObj.Dispose(); } // Update the AnyState, StartState and ConcurrentState if (newState is InternalStateMachine) { var fsm = newState as InternalStateMachine; fsm.startState = null; fsm.concurrentState = null; fsm.anyState = null; } EditorUtility.SetDirty(newState); // Set new parent if (parent != null) { newState.parent = parent; // Update position if (parent == state.parent) newState.position += new Vector2(20f, 20f); } else newState.parent = null; // Saves state and sets dirty flag INodeOwner nodeOwner = newState as INodeOwner; if (nodeOwner != null) { nodeOwner.LoadNodes(); StateUtility.SetDirty(nodeOwner); } else EditorUtility.SetDirty(newState); // Try to get the StartState, AnyState and ConcurrentState if (originalFsm != null) { if (originalFsm.startState == state) startState = newState; if (anyState == null) anyState = newState as InternalAnyState; if (originalFsm.concurrentState == state) concurrentState = newState; } } } } // Set StartState, AnyState and ConcurrentState if (newFsm != null) { if (newFsm.startState == null) newFsm.startState = startState; if (newFsm.anyState == null) newFsm.anyState = anyState; if (newFsm.concurrentState == null) newFsm.concurrentState = concurrentState; EditorUtility.SetDirty(newFsm); } // Try to update the transitions' destination foreach (KeyValuePair<InternalStateBehaviour, InternalStateBehaviour> pair in orginalClone) { InternalStateBehaviour state = pair.Key; InternalStateBehaviour newState = pair.Value; // Update the newState transition for (int i = 0; i < newState.transitions.Length && i < state.transitions.Length; i++) { // The original destination is valid? if (state.transitions[i].destination != null && orginalClone.ContainsKey(state.transitions[i].destination)) newState.transitions[i].destination = orginalClone[state.transitions[i].destination]; } if (newState is ParentBehaviour) { var stateAsParent = state as ParentBehaviour; // Removes the newState from the children state to avoid an infinite loop List<InternalStateBehaviour> children = stateAsParent.states; if (children.Contains(newState)) children.Remove(newState); StateUtility.CloneStates(newState.gameObject, children.ToArray(), newState as ParentBehaviour); } EditorUtility.SetDirty(newState); } EditorUtility.SetDirty(gameObject); } }
protected CharacterAnimator GetAnimations() { ParentBehaviour pb = usingObj.GetComponent <ParentBehaviour>(); return(pb.CharacterAnimations); }
protected UnitKill GetUnitKill() { ParentBehaviour pb = usingObj.GetComponent <ParentBehaviour>(); return(pb.UnitKill); }
public PlayerStats GetStats() { ParentBehaviour pb = usingObj.GetComponent <ParentBehaviour>(); return(pb.Stats); }
/// <summary> /// Class constructor. /// <param name="parent">The target parent to draw the states.</param> /// <param name="serializedProperty">The serializedProperty.isExpanded is used to expand or colapse the states.</param> /// </summary> public ParentStatesEditor (ParentBehaviour parent, SerializedProperty serializedProperty) { m_Parent = parent; m_SerialProp = serializedProperty; }
/// <summary> /// BehaviourMachine callback to update the members. /// </summary> public virtual void UpdateLogic () { // Validate Blackboard if (m_Blackboard == null) m_Blackboard = GetComponent<InternalBlackboard>(); // Validate name if (string.IsNullOrEmpty(m_StateName)) { m_StateName = GetType().Name; } // Validate parent if (m_Parent != null && m_Parent.gameObject != gameObject) { m_Parent = m_LastParent != null && m_LastParent.gameObject == gameObject ? m_LastParent : null; this.enabled = m_Parent == null; } // Check for invalid events destinations for (int i = 0; i < m_Transitions.Length; i++) { // The destination state is not in this game object? var destination = m_Transitions[i].destination; if (destination != null && destination.parent != m_Parent) m_Transitions[i].destination = null; } }
/// <summary> /// Returns True if the supplied parent is an ancestor of the state. /// <param name="parent">The parent to test.</param> /// <returns>True if the node is in the supplied parent hierarchy; False otherwise.</returns> /// </summary> public bool IsAncestor (ParentBehaviour parent) { for (var grandfather = m_Parent; grandfather != null; grandfather = grandfather.parent) { if (grandfather == parent) return true; } return false; }
/// <summary> /// Returns the full state name relative to the parent parent. /// <param name="parent"></param> /// <returns>the full state name relative to supplied parent.</returns> /// </summary> public string GetFullStateNameRelativeTo (ParentBehaviour parent) { return parent != this && m_Parent != null ? (m_Parent.GetFullStateNameRelativeTo(parent) + "/" + m_StateName) : m_StateName; }
public SetParent(InternalStateBehaviour state, ParentBehaviour newParent) { this.state = state; this.newParent = newParent; }
/// <summary> /// Draws the gui control. /// <param name="position">Rectangle on the screen to use for the property GUI.</param> /// <param name="property">The SerializedProperty to make the custom GUI for.</param> /// <param name="label">The label of this property.</param> /// </summary> public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { // Get state var targetState = property.serializedObject.targetObject as InternalStateBehaviour; // It's a valid state? if (targetState != null) { // Draw prefix label #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2 Rect controlPosition = EditorGUI.PrefixLabel(position, EditorGUIUtility.GetControlID(FocusType.Passive, position), label); #else Rect controlPosition = EditorGUI.PrefixLabel(position, label); #endif // Get the parent ParentBehaviour parent = targetState.parent; // Draw button as popup if (GUI.Button(controlPosition, parent != null ? parent.stateName : "Null", EditorStyles.popup)) { // Get valid parents for the state List <ParentBehaviour> validParents = new List <ParentBehaviour>(); var targetParent = targetState as ParentBehaviour; validParents.AddRange(targetState.GetComponents <ParentBehaviour>()); // The target state is a parent behaviour? if (targetParent != null) { for (int i = validParents.Count - 1; i >= 0; i--) { // it's the targetParent? if (validParents[i] == targetParent) { validParents.RemoveAt(i); } // The parent is a child of the target parent? else if (validParents[i].IsAncestor(targetParent)) { validParents.RemoveAt(i); } } } // Create menu var menu = new GenericMenu(); // Add null item menu.AddItem(new GUIContent("Null"), parent == null, this.OnSetNewParent, new SetParent(targetState, null)); // Add menu items var parentNames = new List <string>(); for (int i = 0; i < validParents.Count; i++) { string parentName = StringHelper.GetUniqueNameInList(parentNames, validParents[i].fullStateName); parentNames.Add(parentName); menu.AddItem(new GUIContent(parentName), parent == validParents[i], this.OnSetNewParent, new SetParent(targetState, validParents[i])); } // Show context menu menu.ShowAsContext(); } } }
/// <summary> /// Adds a new root fsm to this blackboard. /// Automatically called by StateMachines and BehaviourTrees. /// The parent should be a root parent, enabled and in the same game object as this blackboard. /// The parents will receive all system events in this game object. /// <param name="parent">The parent to be added to the blackboard.</param> /// </summary> public void AddRootParent (ParentBehaviour parent) { if (parent != null && parent.isRoot && parent.enabled && parent.gameObject == this.gameObject && !m_Parents.Contains(parent)) m_Parents.Add(parent); }
/// <summary> /// Paste the state in StateUtility.stateToPaste in the supplied fsm. /// <param name="parent">The target parent.</param> /// </summary> public static void PasteStates (ParentBehaviour parent) { if (parent != null) CloneStates(parent.gameObject, statesToPaste, parent); }
/// <summary> /// Removes the supplied fsm from this blackboard. /// Automatically called by StateMachines and BehaviourTrees. /// <param name="parent">The parent to be added to the blackboard.</param> /// </summary> public void RemoveRootParent (ParentBehaviour parent) { if (m_Parents.Contains(parent)) m_Parents.Remove(parent); }
/// <summary> /// Class constructor. /// <param name="parent">The target parent to draw the states.</param> /// <param name="serializedProperty">The serializedProperty.isExpanded is used to expand or colapse the states.</param> /// </summary> public ParentStatesEditor(ParentBehaviour parent, SerializedProperty serializedProperty) { m_Parent = parent; m_SerialProp = serializedProperty; }
public SetParent (InternalStateBehaviour state, ParentBehaviour newParent) { this.state = state; this.newParent = newParent; }