예제 #1
0
        void OnEnable()
        {
            BaseState[] states;

            styles = new AIBehaviorsStyles();

            m_Object  = new SerializedObject(target);
            fsm       = m_Object.targetObject as AIBehaviors;
            transform = fsm.transform;

            derivedStateNames = AIBehaviorsComponentInfoHelper.GetStateTypeNames();

            curStateSelection  = 0;
            prevStateSelection = 0;

            // Sorts old states and initializes new states
            InitStates();
            List <BaseState> statesList = new List <BaseState>(fsm.GetAllStates());

            for (int i = 0; i < statesList.Count; i++)
            {
                if (statesList[i] == null)
                {
                    statesList.RemoveAt(i);
                    i--;
                }
            }

            states = statesList.ToArray();
            fsm.ReplaceAllStates(states);

            for (int i = 0; i < states.Length; i++)
            {
                states[i].OnInspectorEnabled(m_Object);
            }

            if (EditorPrefs.HasKey(advancedModeKey))
            {
                advancedMode = EditorPrefs.GetBool(advancedModeKey, false);
            }

            if (EditorPrefs.HasKey(selectedStateKey))
            {
                string stateName = EditorPrefs.GetString(selectedStateKey);

                for (int i = 0; i < states.Length; i++)
                {
                    if (stateName == states[i].name)
                    {
                        curStateSelection  = i;
                        prevStateSelection = i;
                    }
                }
            }
        }
예제 #2
0
        void GetExistingStates()
        {
            BaseState[] states = fsm.GetAllStates();

            foreach (BaseState state in states)
            {
                if (state != null && string.IsNullOrEmpty(state.name))
                {
                    SerializedObject   sObject       = new SerializedObject(state);
                    SerializedProperty mProp         = sObject.FindProperty("name");
                    string             stateTypeName = state.GetType().ToString();

                    mProp.stringValue = AIBehaviorsComponentInfoHelper.GetNameFromType(stateTypeName);
                    sObject.ApplyModifiedProperties();
                }
            }
        }
예제 #3
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.");
            }
        }
예제 #4
0
        void DrawAnimationCallbackSelection()
        {
            Component[]      components = AIBehaviorsComponentInfoHelper.GetNonFSMComponents(fsm.gameObject);
            List <Component> filteredComponents = new List <Component>();
            Component        animCallbackComp = m_Object.FindProperty("animationCallbackComponent").objectReferenceValue as Component;
            string           currentMethodName = m_Object.FindProperty("animationCallbackMethodName").stringValue;
            List <string>    componentNames = new List <string>();
            Dictionary <string, List <string> > methodsList = new Dictionary <string, List <string> >();
            int curComponentIndex = 0, newComponentIndex = 0;
            int curMethodIndex = 0, newMethodIndex = 0;

            GUILayout.BeginVertical(GUI.skin.box);

            GUILayout.Label("Animation Component Callback: ", EditorStyles.boldLabel);

            // Find the current component and potential components that can be a callback

            for (int i = 0; i < components.Length; i++)
            {
                Component    comp     = components[i];
                Type         compType = comp.GetType();
                MethodInfo[] methods  = compType.GetMethods();

                for (int m = 0; m < methods.Length; m++)
                {
                    MethodInfo      mi    = methods[m];
                    ParameterInfo[] parms = mi.GetParameters();

                    if (parms.Length == 1 && parms[0].ParameterType == typeof(AIAnimationState))
                    {
                        string componentName = compType.ToString();

                        if (animCallbackComp != null && compType == animCallbackComp.GetType())
                        {
                            curComponentIndex = componentNames.Count;
                        }

                        if (!methodsList.ContainsKey(componentName))
                        {
                            methodsList[componentName] = new List <string>();
                        }

                        if (currentMethodName == mi.Name)
                        {
                            curMethodIndex = methodsList[componentName].Count;
                        }

                        filteredComponents.Add(comp);
                        componentNames.Add(componentName);
                        methodsList[componentName].Add(mi.Name);
                    }
                    else if (animCallbackComp == comp)
                    {
                        animCallbackComp = null;
                    }
                }
            }

            // If no component was found, show a code sample
            if (componentNames.Count == 0)
            {
                AIBehaviorsCodeSampleGUI.Draw(typeof(AIAnimationState), "animData", "OnAnimationState");
            }
            else
            {
                GUILayoutOption widthOption = GUILayout.MinWidth(75);
                GUILayout.BeginHorizontal();
                GUILayout.Label("Component: ", widthOption);
                newComponentIndex = EditorGUILayout.Popup(curComponentIndex, componentNames.ToArray());
                GUILayout.EndHorizontal();

                GUILayout.BeginHorizontal();
                GUILayout.Label("Method: ", widthOption);
                newMethodIndex = EditorGUILayout.Popup(curMethodIndex, methodsList[componentNames[curComponentIndex]].ToArray());
                GUILayout.EndHorizontal();

                if (curComponentIndex != newComponentIndex || animCallbackComp == null)
                {
                    m_Object.FindProperty("animationCallbackComponent").objectReferenceValue = filteredComponents[newComponentIndex];
                }

                string curComponentName    = componentNames[curComponentIndex];
                string curMethodName       = m_Object.FindProperty("animationCallbackMethodName").stringValue;
                string methodListIndexName = methodsList[curComponentName][newMethodIndex];

                if (curMethodName != methodListIndexName || currentMethodName == "" || currentMethodName == null)
                {
                    m_Object.FindProperty("animationCallbackMethodName").stringValue = methodListIndexName;
                }
            }

            GUILayout.EndVertical();
        }
        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();
        }