mirror of
				https://github.com/DerTyp7/grow-ai-unity.git
				synced 2025-11-04 06:48:58 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			259 lines
		
	
	
		
			9.4 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			259 lines
		
	
	
		
			9.4 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using UnityEngine;
 | 
						|
using UnityEngine.AI;
 | 
						|
 | 
						|
namespace UnityEditor.AI
 | 
						|
{
 | 
						|
    public static class NavMeshComponentsGUIUtility
 | 
						|
    {
 | 
						|
        public static void AreaPopup(string labelName, SerializedProperty areaProperty)
 | 
						|
        {
 | 
						|
            var areaIndex = -1;
 | 
						|
            var areaNames = GameObjectUtility.GetNavMeshAreaNames();
 | 
						|
            for (var i = 0; i < areaNames.Length; i++)
 | 
						|
            {
 | 
						|
                var areaValue = GameObjectUtility.GetNavMeshAreaFromName(areaNames[i]);
 | 
						|
                if (areaValue == areaProperty.intValue)
 | 
						|
                    areaIndex = i;
 | 
						|
            }
 | 
						|
            ArrayUtility.Add(ref areaNames, "");
 | 
						|
            ArrayUtility.Add(ref areaNames, "Open Area Settings...");
 | 
						|
 | 
						|
            var rect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight);
 | 
						|
            EditorGUI.BeginProperty(rect, GUIContent.none, areaProperty);
 | 
						|
 | 
						|
            EditorGUI.BeginChangeCheck();
 | 
						|
            areaIndex = EditorGUI.Popup(rect, labelName, areaIndex, areaNames);
 | 
						|
 | 
						|
            if (EditorGUI.EndChangeCheck())
 | 
						|
            {
 | 
						|
                if (areaIndex >= 0 && areaIndex < areaNames.Length - 2)
 | 
						|
                    areaProperty.intValue = GameObjectUtility.GetNavMeshAreaFromName(areaNames[areaIndex]);
 | 
						|
                else if (areaIndex == areaNames.Length - 1)
 | 
						|
                    NavMeshEditorHelpers.OpenAreaSettings();
 | 
						|
            }
 | 
						|
 | 
						|
            EditorGUI.EndProperty();
 | 
						|
        }
 | 
						|
 | 
						|
        public static void AgentTypePopup(string labelName, SerializedProperty agentTypeID)
 | 
						|
        {
 | 
						|
            var index = -1;
 | 
						|
            var count = NavMesh.GetSettingsCount();
 | 
						|
            var agentTypeNames = new string[count + 2];
 | 
						|
            for (var i = 0; i < count; i++)
 | 
						|
            {
 | 
						|
                var id = NavMesh.GetSettingsByIndex(i).agentTypeID;
 | 
						|
                var name = NavMesh.GetSettingsNameFromID(id);
 | 
						|
                agentTypeNames[i] = name;
 | 
						|
                if (id == agentTypeID.intValue)
 | 
						|
                    index = i;
 | 
						|
            }
 | 
						|
            agentTypeNames[count] = "";
 | 
						|
            agentTypeNames[count + 1] = "Open Agent Settings...";
 | 
						|
 | 
						|
            bool validAgentType = index != -1;
 | 
						|
            if (!validAgentType)
 | 
						|
            {
 | 
						|
                EditorGUILayout.HelpBox("Agent Type invalid.", MessageType.Warning);
 | 
						|
            }
 | 
						|
 | 
						|
            var rect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight);
 | 
						|
            EditorGUI.BeginProperty(rect, GUIContent.none, agentTypeID);
 | 
						|
 | 
						|
            EditorGUI.BeginChangeCheck();
 | 
						|
            index = EditorGUI.Popup(rect, labelName, index, agentTypeNames);
 | 
						|
            if (EditorGUI.EndChangeCheck())
 | 
						|
            {
 | 
						|
                if (index >= 0 && index < count)
 | 
						|
                {
 | 
						|
                    var id = NavMesh.GetSettingsByIndex(index).agentTypeID;
 | 
						|
                    agentTypeID.intValue = id;
 | 
						|
                }
 | 
						|
                else if (index == count + 1)
 | 
						|
                {
 | 
						|
                    NavMeshEditorHelpers.OpenAgentSettings(-1);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            EditorGUI.EndProperty();
 | 
						|
        }
 | 
						|
 | 
						|
        // Agent mask is a set (internally array/list) of agentTypeIDs.
 | 
						|
        // It is used to describe which agents modifiers apply to.
 | 
						|
        // There is a special case of "None" which is an empty array.
 | 
						|
        // There is a special case of "All" which is an array of length 1, and value of -1.
 | 
						|
        public static void AgentMaskPopup(string labelName, SerializedProperty agentMask)
 | 
						|
        {
 | 
						|
            // Contents of the dropdown box.
 | 
						|
            string popupContent = "";
 | 
						|
 | 
						|
            if (agentMask.hasMultipleDifferentValues)
 | 
						|
                popupContent = "\u2014";
 | 
						|
            else
 | 
						|
                popupContent = GetAgentMaskLabelName(agentMask);
 | 
						|
 | 
						|
            var content = new GUIContent(popupContent);
 | 
						|
            var popupRect = GUILayoutUtility.GetRect(content, EditorStyles.popup);
 | 
						|
 | 
						|
            EditorGUI.BeginProperty(popupRect, GUIContent.none, agentMask);
 | 
						|
            popupRect = EditorGUI.PrefixLabel(popupRect, 0, new GUIContent(labelName));
 | 
						|
            bool pressed = GUI.Button(popupRect, content, EditorStyles.popup);
 | 
						|
 | 
						|
            if (pressed)
 | 
						|
            {
 | 
						|
                var show = !agentMask.hasMultipleDifferentValues;
 | 
						|
                var showNone = show && agentMask.arraySize == 0;
 | 
						|
                var showAll = show && IsAll(agentMask);
 | 
						|
 | 
						|
                var menu = new GenericMenu();
 | 
						|
                menu.AddItem(new GUIContent("None"), showNone, SetAgentMaskNone, agentMask);
 | 
						|
                menu.AddItem(new GUIContent("All"), showAll, SetAgentMaskAll, agentMask);
 | 
						|
                menu.AddSeparator("");
 | 
						|
 | 
						|
                var count = NavMesh.GetSettingsCount();
 | 
						|
                for (var i = 0; i < count; i++)
 | 
						|
                {
 | 
						|
                    var id = NavMesh.GetSettingsByIndex(i).agentTypeID;
 | 
						|
                    var sname = NavMesh.GetSettingsNameFromID(id);
 | 
						|
 | 
						|
                    var showSelected = show && AgentMaskHasSelectedAgentTypeID(agentMask, id);
 | 
						|
                    var userData = new object[] { agentMask, id, !showSelected };
 | 
						|
                    menu.AddItem(new GUIContent(sname), showSelected, ToggleAgentMaskItem, userData);
 | 
						|
                }
 | 
						|
 | 
						|
                menu.DropDown(popupRect);
 | 
						|
            }
 | 
						|
 | 
						|
            EditorGUI.EndProperty();
 | 
						|
        }
 | 
						|
 | 
						|
        public static GameObject CreateAndSelectGameObject(string suggestedName, GameObject parent)
 | 
						|
        {
 | 
						|
            var parentTransform = parent != null ? parent.transform : null;
 | 
						|
            var uniqueName = GameObjectUtility.GetUniqueNameForSibling(parentTransform, suggestedName);
 | 
						|
            var child = new GameObject(uniqueName);
 | 
						|
 | 
						|
            Undo.RegisterCreatedObjectUndo(child, "Create " + uniqueName);
 | 
						|
            if (parentTransform != null)
 | 
						|
                Undo.SetTransformParent(child.transform, parentTransform, "Parent " + uniqueName);
 | 
						|
 | 
						|
            Selection.activeGameObject = child;
 | 
						|
 | 
						|
            return child;
 | 
						|
        }
 | 
						|
 | 
						|
        static bool IsAll(SerializedProperty agentMask)
 | 
						|
        {
 | 
						|
            return agentMask.arraySize == 1 && agentMask.GetArrayElementAtIndex(0).intValue == -1;
 | 
						|
        }
 | 
						|
 | 
						|
        static void ToggleAgentMaskItem(object userData)
 | 
						|
        {
 | 
						|
            var args = (object[])userData;
 | 
						|
            var agentMask = (SerializedProperty)args[0];
 | 
						|
            var agentTypeID = (int)args[1];
 | 
						|
            var value = (bool)args[2];
 | 
						|
 | 
						|
            ToggleAgentMaskItem(agentMask, agentTypeID, value);
 | 
						|
        }
 | 
						|
 | 
						|
        static void ToggleAgentMaskItem(SerializedProperty agentMask, int agentTypeID, bool value)
 | 
						|
        {
 | 
						|
            if (agentMask.hasMultipleDifferentValues)
 | 
						|
            {
 | 
						|
                agentMask.ClearArray();
 | 
						|
                agentMask.serializedObject.ApplyModifiedProperties();
 | 
						|
            }
 | 
						|
 | 
						|
            // Find which index this agent type is in the agentMask array.
 | 
						|
            int idx = -1;
 | 
						|
            for (var j = 0; j < agentMask.arraySize; j++)
 | 
						|
            {
 | 
						|
                var elem = agentMask.GetArrayElementAtIndex(j);
 | 
						|
                if (elem.intValue == agentTypeID)
 | 
						|
                    idx = j;
 | 
						|
            }
 | 
						|
 | 
						|
            // Handle "All" special case.
 | 
						|
            if (IsAll(agentMask))
 | 
						|
            {
 | 
						|
                agentMask.DeleteArrayElementAtIndex(0);
 | 
						|
            }
 | 
						|
 | 
						|
            // Toggle value.
 | 
						|
            if (value)
 | 
						|
            {
 | 
						|
                if (idx == -1)
 | 
						|
                {
 | 
						|
                    agentMask.InsertArrayElementAtIndex(agentMask.arraySize);
 | 
						|
                    agentMask.GetArrayElementAtIndex(agentMask.arraySize - 1).intValue = agentTypeID;
 | 
						|
                }
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                if (idx != -1)
 | 
						|
                {
 | 
						|
                    agentMask.DeleteArrayElementAtIndex(idx);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            agentMask.serializedObject.ApplyModifiedProperties();
 | 
						|
        }
 | 
						|
 | 
						|
        static void SetAgentMaskNone(object data)
 | 
						|
        {
 | 
						|
            var agentMask = (SerializedProperty)data;
 | 
						|
            agentMask.ClearArray();
 | 
						|
            agentMask.serializedObject.ApplyModifiedProperties();
 | 
						|
        }
 | 
						|
 | 
						|
        static void SetAgentMaskAll(object data)
 | 
						|
        {
 | 
						|
            var agentMask = (SerializedProperty)data;
 | 
						|
            agentMask.ClearArray();
 | 
						|
            agentMask.InsertArrayElementAtIndex(0);
 | 
						|
            agentMask.GetArrayElementAtIndex(0).intValue = -1;
 | 
						|
            agentMask.serializedObject.ApplyModifiedProperties();
 | 
						|
        }
 | 
						|
 | 
						|
        static string GetAgentMaskLabelName(SerializedProperty agentMask)
 | 
						|
        {
 | 
						|
            if (agentMask.arraySize == 0)
 | 
						|
                return "None";
 | 
						|
 | 
						|
            if (IsAll(agentMask))
 | 
						|
                return "All";
 | 
						|
 | 
						|
            if (agentMask.arraySize <= 3)
 | 
						|
            {
 | 
						|
                var labelName = "";
 | 
						|
                for (var j = 0; j < agentMask.arraySize; j++)
 | 
						|
                {
 | 
						|
                    var elem = agentMask.GetArrayElementAtIndex(j);
 | 
						|
                    var settingsName = NavMesh.GetSettingsNameFromID(elem.intValue);
 | 
						|
                    if (string.IsNullOrEmpty(settingsName))
 | 
						|
                        continue;
 | 
						|
 | 
						|
                    if (labelName.Length > 0)
 | 
						|
                        labelName += ", ";
 | 
						|
                    labelName += settingsName;
 | 
						|
                }
 | 
						|
                return labelName;
 | 
						|
            }
 | 
						|
 | 
						|
            return "Mixed...";
 | 
						|
        }
 | 
						|
 | 
						|
        static bool AgentMaskHasSelectedAgentTypeID(SerializedProperty agentMask, int agentTypeID)
 | 
						|
        {
 | 
						|
            for (var j = 0; j < agentMask.arraySize; j++)
 | 
						|
            {
 | 
						|
                var elem = agentMask.GetArrayElementAtIndex(j);
 | 
						|
                if (elem.intValue == agentTypeID)
 | 
						|
                    return true;
 | 
						|
            }
 | 
						|
            return false;
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |