123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- 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;
- }
- }
- }
|