public override void OnDisable() { base.OnDisable(); StateMachineUtility.CleanUpAll(); StateMachineUtility.CleanUp(machine, machineObject); }
void CleanUp() { for (int i = 0; i < targets.Length; i++) { StateMachine selectedMachine = targets[i] as StateMachine; if (selectedMachine != null) { StateMachineUtility.CleanUp(selectedMachine, selectedMachine.CachedGameObject); } } }
public override void OnEnable() { base.OnEnable(); state = (State)target; if (state.Machine == null) { Type layerType = StateMachineUtility.GetLayerTypeFromState(state); StateMachine machine = state.CachedGameObject.GetOrAddComponent <StateMachine>(); StateMachineUtility.AddLayer(machine, layerType, machine); } }
public override void OnEnable() { base.OnEnable(); layer = (StateLayer)target; if (layer.Machine == null) { Type layerType = layer.GetType(); StateMachine machine = layer.CachedGameObject.GetOrAddComponent <StateMachine>(); StateMachineUtility.AddLayer(machine, layerType, machine); } }
void ShowStates(SerializedProperty statesProperty, StateLayer layer) { for (int i = 0; i < statesProperty.arraySize; i++) { SerializedProperty stateProperty = statesProperty.GetArrayElementAtIndex(i); State state = stateProperty.GetValue <UnityEngine.Object>() as State; if (state == null) { ShowLayer(statesProperty, i); continue; } BeginBox(GetBoxStyle(state)); Foldout(stateProperty, StateMachineUtility.FormatState(state.GetType(), layer).ToGUIContent(), GetStateStyle(state)); Reorderable(statesProperty, i, true); ShowState(stateProperty); EndBox(); } }
GUIContent GetLayerLabel(StateLayer layer) { string label = layer.GetType().Name; if (Application.isPlaying && PrefabUtility.GetPrefabType(machine) != PrefabType.Prefab) { IState[] activeStates = layer.GetActiveStates(); string[] activeStateNames = new string[activeStates.Length]; for (int i = 0; i < activeStateNames.Length; i++) { activeStateNames[i] = activeStates[i] is IStateLayer ? activeStates[i].GetTypeName() : StateMachineUtility.FormatState(activeStates[i].GetType(), layer); } label += " (" + activeStateNames.Concat(", ") + ")"; } return(label.ToGUIContent()); }
void ShowLayerOptions(StateLayer layer, Rect rect) { bool isScrolling = (Screen.width - rect.xMax) > 5; GUIStyle style = new GUIStyle("MiniToolbarPopup"); style.fontStyle = FontStyle.Bold; rect.x = Screen.width - (isScrolling ? 60 : 45) - EditorGUI.indentLevel * 15; rect.y += 1; rect.width = 24 + EditorGUI.indentLevel * 15; if (!Application.isPlaying && (Event.current.type == EventType.ExecuteCommand || rect.Contains(Event.current.mousePosition))) { List <UnityEngine.Object> validParents = new List <UnityEngine.Object>(); List <Type> layerTypes = new List <Type>(); List <string> options = new List <string> { "..." }; bool machineIsParent = StateMachineUtility.IsParent(layer, machine); foreach (KeyValuePair <Type, List <Type> > pair in StateMachineUtility.LayerTypeStateTypeDict) { PropertyInfo layerProperty = pair.Key.GetProperty("Layer", ReflectionExtensions.AllFlags); PropertyInfo machineProperty = pair.Key.GetProperty("Machine", ReflectionExtensions.AllFlags); if ((machineProperty == null || machineProperty.PropertyType.IsInstanceOfType(machine)) && (layerProperty == null || layerProperty.PropertyType.IsInstanceOfType(layer)) && Array.TrueForAll(existingLayers, existingLayer => existingLayer.GetType() != pair.Key)) { layerTypes.Add(pair.Key); options.Add("Add/" + StateMachineUtility.LayerTypeFormattedDict[pair.Key]); } } if (!machineIsParent) { validParents.Add(machine); options.Add("Move To/Machine"); } for (int i = 0; i < existingLayers.Length; i++) { StateLayer existingLayer = existingLayers[i]; if (layer != existingLayer && !StateMachineUtility.IsParent(layer, existingLayer) && !StateMachineUtility.GetSubLayersRecursive(layer).Contains(existingLayer)) { validParents.Add(existingLayer); options.Add("Move To/" + StateMachineUtility.FormatLayer(existingLayer.GetType())); } } options.Add("Copy"); if (EditorPrefs.GetString("Clipboard Layer Type") == layer.GetType().Name) { options.Add("Paste/Layer"); options.Add("Paste/Layer and States"); options.Add("Paste/Layer and Sublayers"); options.Add("Paste/All"); } options.Add("Generate"); if (Selection.gameObjects.Length <= 1) { // int index = EditorGUI.Popup(rect, layerTypes.IndexOf(selectedLayerType) + 1, options.ToArray(), style) - 1; int index = EditorGUI.Popup(rect, 0, options.ToArray(), style) - 1; string option = index == -1 ? "" : options[index + 1]; if (index < layerTypes.Count) { selectedLayerType = index == -1 ? null : layerTypes[Mathf.Clamp(index, 0, options.Count - 1)]; if (selectedLayerType != null) { StateMachineUtility.AddLayer(machine, selectedLayerType, layer); selectedLayerType = null; } } else if (option.StartsWith("Move To")) { UnityEngine.Object parent = validParents[index - layerTypes.Count]; StateMachineUtility.MoveLayerTo(layer, parent); } else if (option.StartsWith("Copy")) { EditorPrefs.SetString("Clipboard Layer Type", layer.GetType().Name); EditorPrefs.SetInt("Clipboard Layer ID", layer.GetInstanceID()); } else if (option.StartsWith("Paste")) { StateLayer layerToCopy = EditorUtility.InstanceIDToObject(EditorPrefs.GetInt("Clipboard Layer ID")) as StateLayer; if (option == "Paste/Layer") { StateMachineUtility.CopyLayer(layer, layerToCopy, false, false); } else if (option == "Paste/Layer and States") { StateMachineUtility.CopyLayer(layer, layerToCopy, true, false); } else if (option == "Paste/Layer and Sublayers") { StateMachineUtility.CopyLayer(layer, layerToCopy, false, true); } else if (option == "Paste/All") { StateMachineUtility.CopyLayer(layer, layerToCopy, true, true); } EditorPrefs.SetString("Clipboard Layer Type", ""); EditorPrefs.SetInt("Clipboard Layer ID", 0); } else if (option.StartsWith("Generate")) { StateMachineGeneratorWindow generator = StateMachineGeneratorWindow.Create(); string layerTypeName = layer.GetTypeName(); string layerScriptPath = AssetDatabaseUtility.GetAssetPath(layerTypeName + ".cs"); generator.Path = string.IsNullOrEmpty(layerScriptPath) ? generator.Path : Path.GetDirectoryName(layerScriptPath); generator.Machine = StateMachineUtility.FormatMachine(machine); generator.Layer = layerTypeName; generator.Inherit = StateMachineUtility.FormatLayer(layer.GetType().BaseType); generator.SubLayer = layer.Layer == null ? "" : StateMachineUtility.FormatLayer(layer.Layer.GetType()); } } } else { EditorGUI.BeginDisabledGroup(Application.isPlaying); EditorGUI.Popup(rect, 0, new[] { "..." }, style); EditorGUI.EndDisabledGroup(); } }
void ShowLayer(SerializedProperty layersProperty, int index) { SerializedProperty layerProperty = layersProperty.GetArrayElementAtIndex(index); StateLayer layer = layerProperty.GetValue <StateLayer>(); SerializedObject layerSerialized = new SerializedObject(layer); SerializedProperty statesProperty = layerSerialized.FindProperty("stateReferences"); SerializedProperty activeStatesProperty = layerSerialized.FindProperty("activeStateReferences"); StateMachineUtility.AddMissingStates(machine, layer); BeginBox(GetBoxStyle(layer)); Rect rect = EditorGUILayout.BeginHorizontal(); ShowLayerOptions(layer, rect); if (DeleteFoldOut(layersProperty, index, GetLayerLabel(layer), GetLayerStyle(layer))) { StateMachineUtility.RemoveLayer(machine, layer); return; } EditorGUILayout.EndHorizontal(); CleanUpStates(statesProperty); if (layerProperty.isExpanded) { EditorGUI.indentLevel += 1; List <string> currentLayerStatesName = new List <string> { "Empty" }; IState[] states = statesProperty.GetValues <IState>(); for (int i = 0; i < states.Length; i++) { IState state = states[i]; currentLayerStatesName.Add(state is IStateLayer ? state.GetTypeName() : StateMachineUtility.FormatState(state.GetType(), layer)); } for (int i = 0; i < activeStatesProperty.arraySize; i++) { SerializedProperty activeStateProperty = activeStatesProperty.GetArrayElementAtIndex(i); UnityEngine.Object activeState = activeStateProperty.objectReferenceValue; if (Selection.gameObjects.Length <= 1) { Rect dragArea = EditorGUILayout.BeginHorizontal(); EditorGUI.BeginChangeCheck(); int stateIndex = EditorGUILayout.Popup(string.Format("Active State ({0})", i), statesProperty.IndexOf(activeState) + 1, currentLayerStatesName.ToArray(), GUILayout.MinWidth(200)) - 1; activeState = stateIndex == -1 ? null : statesProperty.GetValue <UnityEngine.Object>(Mathf.Clamp(stateIndex, 0, statesProperty.arraySize - 1)); activeStateProperty.SetValue(activeState); if (EditorGUI.EndChangeCheck() && Application.isPlaying) { layer.SwitchState(activeState == null ? typeof(EmptyState) : activeState.GetType(), i); } if (i == 0) { SmallAddButton(activeStatesProperty); } else if (DeleteButton(activeStatesProperty, i)) { break; } EditorGUILayout.EndHorizontal(); Reorderable(activeStatesProperty, i, true, EditorGUI.IndentedRect(dragArea)); } else { GUI.Box(EditorGUI.IndentedRect(EditorGUILayout.GetControlRect()), "Multi-editing is not supported.", new GUIStyle(EditorStyles.helpBox)); } } Separator(); ShowLayerFields(layerSerialized); bool stateSeparator = statesProperty.arraySize > 0; layerSerialized.ApplyModifiedProperties(); ShowStates(statesProperty, layer); if (stateSeparator) { Separator(); } EditorGUI.indentLevel -= 1; } EndBox(); }
void ShowAddLayer() { GUIStyle style = new GUIStyle("popup"); style.fontStyle = FontStyle.Bold; style.alignment = TextAnchor.MiddleCenter; EditorGUILayout.BeginHorizontal(); if (!Application.isPlaying) { List <Type> layerTypes = new List <Type>(); List <string> layerTypesName = new List <string> { "Add Layer" }; foreach (KeyValuePair <Type, List <Type> > pair in StateMachineUtility.LayerTypeStateTypeDict) { PropertyInfo machineProperty = pair.Key.GetProperty("Machine", ReflectionExtensions.AllFlags); PropertyInfo layerProperty = pair.Key.GetProperty("Layer", ReflectionExtensions.AllFlags); bool machinePropertyValid = machineProperty.PropertyType == typeof(IStateMachine) || machineProperty.PropertyType.IsInstanceOfType(machine); bool layerPropertyValid = layerProperty.PropertyType == typeof(IStateLayer) && Array.TrueForAll(existingLayers, existingLayer => existingLayer.GetType() != pair.Key); if (machinePropertyValid && layerPropertyValid) { layerTypes.Add(pair.Key); layerTypesName.Add(StateMachineUtility.LayerTypeFormattedDict[pair.Key]); } } if (Selection.gameObjects.Length <= 1) { int layerTypeIndex = EditorGUILayout.Popup(layerTypes.IndexOf(selectedLayerType) + 1, layerTypesName.ToArray(), style) - 1; selectedLayerType = layerTypeIndex == -1 ? null : layerTypes[Mathf.Clamp(layerTypeIndex, 0, layerTypes.Count - 1)]; if (selectedLayerType != null) { StateMachineUtility.AddLayer(machine, selectedLayerType, machine); selectedLayerType = null; } } else { GUI.Box(EditorGUI.IndentedRect(EditorGUILayout.GetControlRect()), "Multi-editing is not supported.", new GUIStyle(EditorStyles.helpBox)); } } else { EditorGUI.BeginDisabledGroup(Application.isPlaying); EditorGUILayout.Popup(0, new[] { "Add Layer" }, style); EditorGUI.EndDisabledGroup(); } if (GUILayout.Button("Generate".ToGUIContent())) { StateMachineGeneratorWindow window = StateMachineGeneratorWindow.Create(); window.Machine = StateMachineUtility.FormatMachine(machine); window.Layer = ""; window.Inherit = "PStateLayer"; window.SubLayer = ""; } EditorGUILayout.EndHorizontal(); Separator(); }