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