Exemplo n.º 1
0
        void InitNewStates()
        {
            Dictionary <string, Type> statesDictionary = new Dictionary <string, Type>();
            List <BaseState>          statesList       = new List <BaseState>();
            bool isMecanim = fsm.GetComponent <Animator>() != null;

            // Setup a dictionary of the default states
            statesDictionary["Idle"]   = typeof(IdleState);
            statesDictionary["Patrol"] = typeof(PatrolState);
            statesDictionary["Seek"]   = typeof(SeekState);
            statesDictionary["Flee"]   = typeof(FleeState);

            if (isMecanim)
            {
                statesDictionary["Attack"] = typeof(MecanimAttackState);
            }
            else
            {
                statesDictionary["Attack"] = typeof(AttackState);
            }

            statesDictionary["Defend"]   = typeof(DefendState);
            statesDictionary["Got Hit"]  = typeof(GotHitState);
            statesDictionary["Change"]   = typeof(ChangeState);
            statesDictionary["Help"]     = typeof(HelpState);
            statesDictionary["Get Help"] = typeof(GetHelpState);
            statesDictionary["Dead"]     = typeof(DeadState);

            foreach (string stateName in statesDictionary.Keys)
            {
                string stateClassName = statesDictionary[stateName].Name;

                try
                {
                    BaseState baseState = ComponentHelper.AddComponentByName(statesGameObject, stateClassName) as BaseState;
                    baseState.name = stateName;

                    statesList.Add(baseState);
                }
                catch
                {
                    Debug.LogError("Type \"" + stateClassName + "\" does not exist.  You must have a class named \"" + stateClassName + "\" that derives from \"StateBase\".");
                    inittedSuccessfully = false;
                }
            }

            fsm.ReplaceAllStates(statesList.ToArray());
        }
Exemplo n.º 2
0
        public static void EnableRichAstar()
        {
            GameObject gameObject = GetGameObject();

            string[] components = new string[] { "AstarRichAICharacterController", "AIBehaviors", "CharacterAnimator", "RichAI" };

            ReplaceStringInAstarCode("AstarRichAICharacterController", "//#define USE_ASTAR", "#define USE_ASTAR");

            AssetDatabase.Refresh();

            for (int i = 0; i < components.Length; i++)
            {
                if (gameObject.GetComponent(components[i]) == null)
                {
                    ComponentHelper.AddComponentByName(gameObject, components[i]);
                }
            }
        }
        private static bool DrawTriggerSelectionPopup(string[] triggerTypeNames, ref SerializedProperty triggersProperty, int index)
        {
            BaseTrigger trigger          = triggersProperty.GetArrayElementAtIndex(index).objectReferenceValue as BaseTrigger;
            int         initialSelection = 0;
            int         newSelection     = 0;

            for (int i = 0; i < triggerTypeNames.Length; i++)
            {
                if (trigger != null)
                {
                    if (trigger.GetType().Name == triggerTypeNames[i])
                    {
                        initialSelection = i;
                        break;
                    }
                }
            }

            newSelection = EditorGUILayout.Popup(initialSelection, triggerTypeNames, EditorStyles.popup);

            if (newSelection != initialSelection)
            {
                GameObject    triggerObject = trigger.gameObject;
                BaseTrigger[] triggers      = trigger.subTriggers;
                BaseTrigger   newTrigger;

                                #if UNITY_4_3
                Undo.RegisterFullObjectHierarchyUndo(triggerObject.transform.root.gameObject);
                                #else
                Undo.RegisterFullObjectHierarchyUndo(triggerObject.transform.root.gameObject, "AddTrigger");
                                #endif

                newTrigger = ComponentHelper.AddComponentByName(triggerObject, triggerTypeNames[newSelection]) as BaseTrigger;
                Object.DestroyImmediate(trigger, true);
                newTrigger.subTriggers = triggers;
                triggersProperty.GetArrayElementAtIndex(index).objectReferenceValue = newTrigger;

                return(true);
            }

            return(false);
        }
Exemplo n.º 4
0
        public override void OnInspectorGUI()
        {
            BaseState[] states = fsm.GetAllStates();

            if (prevStateSelection != curStateSelection)
            {
                prevStateSelection = curStateSelection;
                EditorUtility.SetDirty(fsm.GetStateByIndex(curStateSelection));
            }

            if (inittedSuccessfully)
            {
                m_Object.Update();

                if (curStateSelection >= states.Length)
                {
                    curStateSelection = 0;
                }

                GUILayout.Space(10);
                GUILayout.BeginVertical(GUI.skin.box);
                GUILayout.Space(10);

                for (int i = 0; i < fsm.stateCount; i++)
                {
                    string stateDisplayName;

                    if (states[i] == null || states[i].name == null)
                    {
                        Undo.RecordObject(fsm, "Removed null state");
                        AIBehaviorsAssignableObjectArray.RemoveObjectAtIndex(m_Object, i, "states");
                        m_Object.ApplyModifiedProperties();
                        return;
                    }

                    stateDisplayName = states[i].name;

                    GUILayout.BeginHorizontal();
                    {
                        const int guiWidths = 90;

                        if (GUILayout.Button("Edit", GUILayout.MaxWidth(50)))
                        {
                            curStateSelection = i;

                            EditorPrefs.SetString(selectedStateKey, stateDisplayName);
                        }

                        GUILayout.Space(10);

                        Color  oldColor = GUI.color;
                        string updatedName;

                        if (Application.isPlaying && states[i] == fsm.currentState)
                        {
                            GUI.color = Color.green;
                        }
                        else if (!Application.isPlaying && states[i] == fsm.initialState)
                        {
                            GUI.color = Color.green;
                        }

                        updatedName = GUILayout.TextField(states[i].name, GUILayout.MaxWidth(guiWidths));

                        GUI.color = oldColor;

                        UpdateStateName(updatedName, states[i]);

                        int curState = 0;
                        int newIndex = 0;

                        for (int j = 0; j < derivedStateNames.Length; j++)
                        {
                            if (states[i].GetType().Name == derivedStateNames[j])
                            {
                                curState = j;
                                break;
                            }
                        }

                        newIndex = EditorGUILayout.Popup(curState, derivedStateNames, GUILayout.MaxWidth(guiWidths));

                        if (curState != newIndex)
                        {
                            SerializedProperty m_Prop = m_Object.FindProperty(string.Format(kStatesArrayData, i));
                            string             newName;

                            DestroyImmediate(m_Prop.objectReferenceValue);
                            string typeName = derivedStateNames[newIndex];
                            m_Prop.objectReferenceValue = ComponentHelper.AddComponentByName(fsm.statesGameObject, typeName);
                            newName = AIBehaviorsComponentInfoHelper.GetNameFromType(typeName);
                            UpdateStateName(newName, (m_Prop.objectReferenceValue as BaseState));
                        }

                        // Draw Up, Down, and Remove
                        bool oldEnabled = GUI.enabled;
                        GUI.enabled = i != 0;
                        if (GUILayout.Button(styles.blankContent, styles.upStyle, GUILayout.MaxWidth(styles.arrowButtonWidths)))
                        {
                            AIBehaviorsAssignableObjectArray.Swap(m_Object, i, i - 1, kStatesArrayData);
                        }

                        GUI.enabled = i < states.Length - 1;
                        if (GUILayout.Button(styles.blankContent, styles.downStyle, GUILayout.MaxWidth(styles.arrowButtonWidths)))
                        {
                            AIBehaviorsAssignableObjectArray.Swap(m_Object, i, i + 1, kStatesArrayData);
                        }

                        GUI.enabled = true;


                        if (GUILayout.Button(styles.blankContent, styles.addStyle, GUILayout.MaxWidth(styles.addRemoveButtonWidths)))
                        {
                            SerializedProperty prop = m_Object.FindProperty("states");
                            prop.InsertArrayElementAtIndex(i);
                            BaseState prevState = m_Object.FindProperty(string.Format(kStatesArrayData, i)).objectReferenceValue as BaseState;
                            string    typeName  = prevState.GetType().Name;
                            BaseState newState  = ComponentHelper.AddComponentByName(statesGameObject, typeName) as BaseState;
                            newState.name = prevState.name;
                            UpdateStateName(prevState.name, newState);
                            m_Object.FindProperty(string.Format(kStatesArrayData, i + 1)).objectReferenceValue = newState;
                            Undo.RegisterCreatedObjectUndo(statesGameObject, "Added New State");
                        }

                        GUI.enabled = states.Length > 1;
                        if (GUILayout.Button(styles.blankContent, styles.removeStyle, GUILayout.MaxWidth(styles.addRemoveButtonWidths)))
                        {
                            BaseState state = m_Object.FindProperty(string.Format(kStatesArrayData, i)).objectReferenceValue as BaseState;

                            Undo.RecordObject(state, "Remove a State");

                            foreach (BaseTrigger trigger in state.triggers)
                            {
                                DestroyImmediate(trigger, true);
                            }

                            DestroyImmediate(state, true);

                            AIBehaviorsAssignableObjectArray.RemoveObjectAtIndex(m_Object, i, "states");
                            m_Object.ApplyModifiedProperties();
                            return;
                        }

                        GUI.enabled = oldEnabled;

                        if (EditorGUILayout.Toggle(styles.blankContent, states[i].isEnabled, GUILayout.MaxWidth(25)) != states[i].isEnabled)
                        {
                            states[i].isEnabled = !states[i].isEnabled;
                        }
                    }
                    GUILayout.EndHorizontal();
                }

                EditorGUILayout.Separator();
                DrawInitialStatePopup();

                GUILayout.EndVertical();

                EditorGUILayout.Separator();
                DrawGeneralAgentProperties();

                EditorGUILayout.Separator();
                fsm.objectFinder.DrawPlayerTagsSelection(fsm, m_Object, "objectFinder", true);

                AIBehaviorsTriggersGUI.Draw(m_Object, fsm, "Global Triggers:", "AIBehaviors_GlobalTriggersFoldout");

                EditorGUILayout.Separator();
                DrawAnimationCallbackSelection();

                m_Object.ApplyModifiedProperties();

                // Draw Individual states below

                AIBehaviorsGeneralEditorGUI.Separator();
                GUILayout.BeginHorizontal();
                GUILayout.Label("");
                GUILayout.Label("-- " + states[curStateSelection].name + " (" + states[curStateSelection].GetType().ToString() + ") --", EditorStyles.boldLabel);
                GUILayout.Label("");
                GUILayout.EndHorizontal();
                AIBehaviorsGeneralEditorGUI.Separator();
                states[curStateSelection].DrawInspectorEditor(fsm);

                EditorGUILayout.Separator();
            }
            else
            {
                GUI.contentColor = Color.red;
                GUILayout.Label("You must fix your errors before editting.");
            }
        }
        private static void DrawSubTriggers(SerializedProperty triggerProperty, AIBehaviorsStyles styles, int insetSpace, AIBehaviors fsm, string[] triggerTypeNames, string[] subTriggerTypeNames)
        {
            BaseTrigger        trigger             = triggerProperty.objectReferenceValue as BaseTrigger;
            SerializedObject   triggerObject       = new SerializedObject(triggerProperty.objectReferenceValue);
            SerializedProperty subTriggersProperty = triggerObject.FindProperty("subTriggers");

            if (trigger.subTriggers.Length > 0)
            {
                GUILayout.BeginVertical(GUI.skin.box);
                {
                    int arraySize = trigger.subTriggers.Length;

                    for (int i = 0; i < arraySize; i++)
                    {
                        bool removedAnElement = false;

                        GUILayout.BeginHorizontal();
                        {
                            GUILayout.Space(insetSpace);
                            removedAnElement = DrawTriggerSelectionPopup(subTriggerTypeNames, ref subTriggersProperty, i);

                            if (!removedAnElement)
                            {
                                removedAnElement = DrawArrowsPlusAndMinus(i, arraySize, ref triggerObject, ref subTriggersProperty, styles, "subTriggers", triggerTypeNames[0]);
                            }
                        }
                        GUILayout.EndHorizontal();

                        if (removedAnElement)
                        {
                            break;
                        }

                        GUILayout.BeginHorizontal();
                        {
                            GUILayout.Space(insetSpace);

                            GUILayout.BeginVertical();
                            {
                                trigger.subTriggers[i].DrawInspectorGUI(fsm);

                                DrawSubTriggers(subTriggersProperty.GetArrayElementAtIndex(i), styles, insetSpace + subTriggersInsetAmount, fsm, triggerTypeNames, subTriggerTypeNames);
                            }
                            GUILayout.EndVertical();
                        }
                        GUILayout.EndHorizontal();
                    }
                }
                GUILayout.EndVertical();
            }

            GUILayout.BeginHorizontal();
            {
                GUILayout.Space(insetSpace);
                if (GUILayout.Button(styles.blankContent, styles.addStyle, GUILayout.MaxWidth(styles.addRemoveButtonWidths)))
                {
                    GameObject go        = trigger.gameObject;
                    int        arraySize = subTriggersProperty.arraySize;

                                        #if UNITY_4_3
                    Undo.RegisterFullObjectHierarchyUndo(fsm.gameObject);
                                        #else
                    Undo.RegisterFullObjectHierarchyUndo(fsm.gameObject, "AddSubTrigger");
                                        #endif

                    subTriggersProperty.arraySize++;
                    subTriggersProperty.GetArrayElementAtIndex(arraySize).objectReferenceValue = ComponentHelper.AddComponentByName(go, triggerTypeNames[0]);
                }
            }
            GUILayout.EndHorizontal();

            triggerObject.ApplyModifiedProperties();
        }
        public static void Draw(SerializedObject m_Object, AIBehaviors fsm, string foldoutLabel, string foldoutValueKey)
        {
            string[]           triggerTypeNames    = AIBehaviorsComponentInfoHelper.GetTriggerTypeNames();
            string[]           subTriggerTypeNames = AIBehaviorsComponentInfoHelper.GetTriggerTypeNames(true);
            SerializedProperty triggersProperty    = m_Object.FindProperty("triggers");
            AIBehaviorsStyles  styles = new AIBehaviorsStyles();
            bool foldoutValue         = false;
            bool newFoldoutValue      = false;

            EditorGUILayout.Separator();

            if (EditorPrefs.HasKey(foldoutValueKey))
            {
                foldoutValue = EditorPrefs.GetBool(foldoutValueKey);
            }

            newFoldoutValue = EditorGUILayout.Foldout(foldoutValue, foldoutLabel, EditorStyles.foldoutPreDrop);

            if (foldoutValue != newFoldoutValue)
            {
                foldoutValue = newFoldoutValue;
                EditorPrefs.SetBool(foldoutValueKey, foldoutValue);
            }

            if (!foldoutValue)
            {
                return;
            }

            int  arraySize = triggersProperty.arraySize;
            bool arrayIndexRemoved;

            for (int i = 0; i < arraySize; i++)
            {
                GUILayout.BeginVertical(GUI.skin.box);
                {
                    GUILayout.BeginHorizontal();
                    {
                        arrayIndexRemoved = DrawTriggerSelectionPopup(triggerTypeNames, ref triggersProperty, i);

                        if (!arrayIndexRemoved)
                        {
                            arrayIndexRemoved = DrawArrowsPlusAndMinus(i, arraySize, ref m_Object, ref triggersProperty, styles, "triggers", triggerTypeNames[0]);
                        }
                    }
                    GUILayout.EndHorizontal();

                    if (arrayIndexRemoved)
                    {
                        arraySize--;
                    }
                    else
                    {
                        BaseTrigger baseTrigger = triggersProperty.GetArrayElementAtIndex(i).objectReferenceValue as BaseTrigger;

                        if (baseTrigger == null)
                        {
                            Debug.LogError("Null trigger deleted!");
                            triggersProperty.DeleteArrayElementAtIndex(i);
                        }
                        else
                        {
                            baseTrigger.DrawInspectorGUI(fsm);

                            DrawSubTriggers(triggersProperty.GetArrayElementAtIndex(i), styles, subTriggersInsetAmount, fsm, triggerTypeNames, subTriggerTypeNames);
                            baseTrigger.DrawTransitionState(fsm);
                        }
                    }
                }
                GUILayout.EndVertical();
            }

            if (GUILayout.Button(styles.blankContent, styles.addStyle, GUILayout.MaxWidth(styles.addRemoveButtonWidths)))
            {
                Component result = null;

                for (int i = 0; i < triggerTypeNames.Length; i++)
                {
                    result = ComponentHelper.AddComponentByName(fsm.statesGameObject, triggerTypeNames[i]);

                    if (result != null)
                    {
                        break;
                    }
                }

                triggersProperty.arraySize++;
                triggersProperty.GetArrayElementAtIndex(arraySize).objectReferenceValue = result;
            }

            m_Object.ApplyModifiedProperties();
        }
        private static bool DrawArrowsPlusAndMinus(int index, int arraySize, ref SerializedObject m_Object, ref SerializedProperty triggersProperty, AIBehaviorsStyles styles, string propertyName, string firstTriggerType)
        {
            SerializedProperty prop = triggersProperty.GetArrayElementAtIndex(index);

            if (prop != null)
            {
                Object obj = prop.objectReferenceValue;

                if (obj != null)
                {
                    bool oldEnabled = GUI.enabled;

                    GUI.enabled = index > 0;
                    if (GUILayout.Button(styles.blankContent, styles.upStyle, GUILayout.MaxWidth(styles.arrowButtonWidths)))
                    {
                        triggersProperty.MoveArrayElement(index, index - 1);
                    }

                    GUI.enabled = index < arraySize - 1;
                    if (GUILayout.Button(styles.blankContent, styles.downStyle, GUILayout.MaxWidth(styles.arrowButtonWidths)))
                    {
                        triggersProperty.MoveArrayElement(index, index + 1);
                    }

                    GUI.enabled = true;
                    if (GUILayout.Button(styles.blankContent, styles.addStyle, GUILayout.MaxWidth(styles.addRemoveButtonWidths)))
                    {
                        GameObject go = (m_Object.targetObject as Component).gameObject;

                        triggersProperty.InsertArrayElementAtIndex(index);
                        triggersProperty.GetArrayElementAtIndex(index + 1).objectReferenceValue = ComponentHelper.AddComponentByName(go, firstTriggerType);
                    }

                    if (GUILayout.Button(styles.blankContent, styles.removeStyle, GUILayout.MaxWidth(styles.addRemoveButtonWidths)))
                    {
                        BaseTrigger baseTrigger = prop.objectReferenceValue as BaseTrigger;

                                                #if UNITY_4_3
                        Undo.RegisterFullObjectHierarchyUndo(baseTrigger);
                                                #else
                        Undo.RegisterFullObjectHierarchyUndo(baseTrigger, "RemovedTrigger");
                                                #endif

                        AIBehaviorsAssignableObjectArray.RemoveObjectAtIndex(m_Object, index, propertyName);
                        DestroyTriggers(baseTrigger.subTriggers);
                        Object.DestroyImmediate(baseTrigger, true);

                        return(true);
                    }

                    GUI.enabled = oldEnabled;
                }
            }

            return(false);
        }