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]];
    }
Пример #2
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;
                    }
                }
            }
        }
	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();
	}
Пример #4
0
    // 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);
        }
    }
Пример #5
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.");
            }
        }
	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.");
		}
	}