public static BaseState DrawEnabledStatePopup(AIBehaviors fsm, BaseState curState) { List<string> statesList = new List<string>(); Dictionary<string, BaseState> statesDictionary = new Dictionary<string, BaseState>(); BaseState[] states = fsm.GetAllStates(); string[] stateSelections; int selection = 0; // Get the state names for ( int i = 0; i < fsm.stateCount; i++ ) { // Should we include state i in the list? if ( states[i].isEnabled ) { string stateName = states[i].name; statesList.Add(stateName); statesDictionary[stateName] = states[i]; if ( states[i] == curState ) { selection = statesList.Count-1; } } } stateSelections = statesList.ToArray(); selection = EditorGUILayout.Popup(selection, stateSelections); return statesDictionary[stateSelections[selection]]; }
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 OnEnable() { BaseState[] states; m_Object = new SerializedObject(target); fsm = m_Object.targetObject as AIBehaviors; transform = fsm.transform; derivedStateNames = AIBehaviorsComponentInfoHelper.GetStateTypeNames(); curStateSelection = 0; prevStateSelection = 0; AIBehaviorsLegacy.UpgradeTriggers(fsm); // Sorts old states and initializes new states InitStates(); states = fsm.GetAllStates(); for ( int i = 0; i < fsm.stateCount; 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; } } } MarkStatesAsUpgraded(); }
// Change the other FSMs state to the HelpState private void HelpAnotherFSM(Vector3 otherFSMPosition, AIBehaviors fsm) { HelpState helpState = null; BaseState[] states = fsm.GetAllStates(); foreach ( BaseState state in states ) { if ( state.GetType() == typeof(HelpState) ) { helpState = state as HelpState; break; } } if ( helpState != null ) { helpState.helpPoint = otherFSMPosition; fsm.ChangeActiveState(helpState); } }
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."); } }
public static void UpgradeTriggers(AIBehaviors fsm) { bool upgradedTriggers = false; BaseState[] states = fsm.GetAllStates(); foreach ( BaseState state in states ) { List<BaseTrigger> newTriggers = new List<BaseTrigger>(); #if UNITY_EDITOR GameObject triggersGameObject; Transform fsmTransform; SerializedObject obj = new SerializedObject(state); SerializedProperty prop = null; if ( state.isUpgraded ) continue; if ( Application.isPlaying ) { triggersGameObject = fsm.statesGameObject; fsmTransform = fsm.transform; } else if ( Selection.activeTransform != null ) { fsmTransform = Selection.activeTransform; triggersGameObject = fsmTransform.gameObject; } else { return; } foreach ( Transform tfm in fsmTransform ) { if ( tfm.name == "States" ) { if (tfm.gameObject.GetInstanceID() == fsm.statesGameObject.GetInstanceID() ) { triggersGameObject = tfm.gameObject; } } } #else GameObject triggersGameObject = fsm.statesGameObject; #endif if ( state.usesLineOfSightTrigger ) { LineOfSightTrigger trigger = triggersGameObject.AddComponent<LineOfSightTrigger>(); trigger.transitionState = state.lineOfSightState; newTriggers.Add(trigger); } if ( state.usesNoPlayerInSightTrigger ) { NoPlayerInSightTrigger trigger = triggersGameObject.AddComponent<NoPlayerInSightTrigger>(); trigger.transitionState = state.noPlayerInSightState; newTriggers.Add(trigger); } if ( state.usesWithinDistanceTrigger ) { WithinDistanceTrigger trigger = triggersGameObject.AddComponent<WithinDistanceTrigger>(); trigger.distanceThreshold = state.withinDistance; trigger.transitionState = state.withinDistanceState; state.usesWithinDistanceTrigger = false; newTriggers.Add(trigger); } if ( state.usesBeyondDistanceTrigger ) { BeyondDistanceTrigger trigger = triggersGameObject.AddComponent<BeyondDistanceTrigger>(); trigger.distanceThreshold = state.beyondDistance; trigger.transitionState = state.beyondDistanceState; newTriggers.Add(trigger); } if ( state.usesTimerTrigger ) { TimerTrigger trigger = triggersGameObject.AddComponent<TimerTrigger>(); trigger.duration = state.timerDuration; trigger.transitionState = state.timerExpiredState; newTriggers.Add(trigger); } if ( state.usesLowHealthTrigger ) { LowHealthTrigger trigger = triggersGameObject.AddComponent<LowHealthTrigger>(); trigger.healthThreshold = state.lowHealthAmount; trigger.transitionState = state.lowHealthState; newTriggers.Add(trigger); } if ( state.usesHighHealthTrigger ) { HighHealthTrigger trigger = triggersGameObject.AddComponent<HighHealthTrigger>(); trigger.healthThreshold = state.highHealthAmount; trigger.transitionState = state.highHealthState; newTriggers.Add(trigger); } if ( state.usesInPlayerViewTrigger ) { InPlayerViewTrigger trigger = triggersGameObject.AddComponent<InPlayerViewTrigger>(); trigger.transitionState = state.inPlayerViewState; newTriggers.Add(trigger); } if ( newTriggers.Count > 0 ) { upgradedTriggers = true; #if UNITY_EDITOR prop = obj.FindProperty("triggers"); prop.arraySize = newTriggers.Count; for ( int i = 0; i < newTriggers.Count; i++ ) { const string kArrayData = "triggers.Array.data[{0}]"; prop = obj.FindProperty(string.Format(kArrayData, i)); prop.objectReferenceValue = newTriggers[i]; Debug.Log(state.GetType().ToString() + " : " + newTriggers[i].GetType().ToString()); } obj.FindProperty("usesLineOfSightTrigger").boolValue = false; obj.FindProperty("usesNoPlayerInSightTrigger").boolValue = false; obj.FindProperty("usesWithinDistanceTrigger").boolValue = false; obj.FindProperty("usesBeyondDistanceTrigger").boolValue = false; obj.FindProperty("usesTimerTrigger").boolValue = false; obj.FindProperty("usesLowHealthTrigger").boolValue = false; obj.FindProperty("usesHighHealthTrigger").boolValue = false; obj.FindProperty("usesInPlayerViewTrigger").boolValue = false; obj.ApplyModifiedProperties(); #else state.triggers = newTriggers.ToArray(); state.usesLineOfSightTrigger = false; state.usesNoPlayerInSightTrigger = false; state.usesWithinDistanceTrigger = false; state.usesBeyondDistanceTrigger = false; state.usesTimerTrigger = false; state.usesLowHealthTrigger = false; state.usesHighHealthTrigger = false; #endif } } if ( Application.isPlaying && upgradedTriggers ) { Debug.LogWarning("Please click on the '" + fsm.name + "' AIBehaviors object in edit mode to upgrade to the new triggers system."); } else if ( upgradedTriggers ) { Debug.LogWarning("Upgraded '" + fsm.name + "'. Some things may have broken in the process."); } }