示例#1
0
        public override void OnDisable()
        {
            base.OnDisable();

            StateMachineUtility.CleanUpAll();
            StateMachineUtility.CleanUp(machine, machineObject);
        }
示例#2
0
        void CleanUp()
        {
            for (int i = 0; i < targets.Length; i++)
            {
                StateMachine selectedMachine = targets[i] as StateMachine;

                if (selectedMachine != null)
                {
                    StateMachineUtility.CleanUp(selectedMachine, selectedMachine.CachedGameObject);
                }
            }
        }
示例#3
0
        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);
            }
        }
示例#4
0
        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);
            }
        }
示例#5
0
        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();
            }
        }
示例#6
0
        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());
        }
示例#7
0
        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();
            }
        }
示例#8
0
        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();
        }
示例#9
0
        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();
        }