123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using UnityEditor;
- using UnityEditorInternal;
- using UnityEngine;
- namespace Mirror
- {
- [CustomEditor(typeof(NetworkManager), true)]
- [CanEditMultipleObjects]
- public class NetworkManagerEditor : Editor
- {
- SerializedProperty spawnListProperty;
- ReorderableList spawnList;
- protected NetworkManager networkManager;
- protected void Init()
- {
- if (spawnList == null)
- {
- networkManager = target as NetworkManager;
- spawnListProperty = serializedObject.FindProperty("spawnPrefabs");
- spawnList = new ReorderableList(serializedObject, spawnListProperty)
- {
- drawHeaderCallback = DrawHeader,
- drawElementCallback = DrawChild,
- onReorderCallback = Changed,
- onRemoveCallback = RemoveButton,
- onChangedCallback = Changed,
- onAddCallback = AddButton,
- // this uses a 16x16 icon. other sizes make it stretch.
- elementHeight = 16
- };
- }
- }
- public override void OnInspectorGUI()
- {
- Init();
- DrawDefaultInspector();
- EditorGUI.BeginChangeCheck();
- spawnList.DoLayoutList();
- if (EditorGUI.EndChangeCheck())
- {
- serializedObject.ApplyModifiedProperties();
- }
- if (GUILayout.Button("Populate Spawnable Prefabs"))
- {
- ScanForNetworkIdentities();
- }
- }
- void ScanForNetworkIdentities()
- {
- List<GameObject> identities = new List<GameObject>();
- bool cancelled = false;
- try
- {
- string[] paths = EditorHelper.IterateOverProject("t:prefab").ToArray();
- int count = 0;
- foreach (string path in paths)
- {
- // ignore test & example prefabs.
- // users sometimes keep the folders in their projects.
- if (path.Contains("Mirror/Tests/") ||
- path.Contains("Mirror/Examples/"))
- {
- continue;
- }
- if (EditorUtility.DisplayCancelableProgressBar("Searching for NetworkIdentities..",
- $"Scanned {count}/{paths.Length} prefabs. Found {identities.Count} new ones",
- count / (float)paths.Length))
- {
- cancelled = true;
- break;
- }
- count++;
- NetworkIdentity ni = AssetDatabase.LoadAssetAtPath<NetworkIdentity>(path);
- if (!ni)
- {
- continue;
- }
- if (!networkManager.spawnPrefabs.Contains(ni.gameObject))
- {
- identities.Add(ni.gameObject);
- }
- }
- }
- finally
- {
- EditorUtility.ClearProgressBar();
- if (!cancelled)
- {
- // RecordObject is needed for "*" to show up in Scene.
- // however, this only saves List.Count without the entries.
- Undo.RecordObject(networkManager, "NetworkManager: populated prefabs");
- // add the entries
- networkManager.spawnPrefabs.AddRange(identities);
- // sort alphabetically for better UX
- networkManager.spawnPrefabs = networkManager.spawnPrefabs.OrderBy(go => go.name).ToList();
- // SetDirty is required to save the individual entries properly.
- EditorUtility.SetDirty(target);
- }
- // Loading assets might use a lot of memory, so try to unload them after
- Resources.UnloadUnusedAssets();
- }
- }
- static void DrawHeader(Rect headerRect)
- {
- GUI.Label(headerRect, "Registered Spawnable Prefabs:");
- }
- internal void DrawChild(Rect r, int index, bool isActive, bool isFocused)
- {
- SerializedProperty prefab = spawnListProperty.GetArrayElementAtIndex(index);
- GameObject go = (GameObject)prefab.objectReferenceValue;
- GUIContent label;
- if (go == null)
- {
- label = new GUIContent("Empty", "Drag a prefab with a NetworkIdentity here");
- }
- else
- {
- NetworkIdentity identity = go.GetComponent<NetworkIdentity>();
- label = new GUIContent(go.name, identity != null ? $"AssetId: [{identity.assetId}]" : "No Network Identity");
- }
- GameObject newGameObject = (GameObject)EditorGUI.ObjectField(r, label, go, typeof(GameObject), false);
- if (newGameObject != go)
- {
- if (newGameObject != null && !newGameObject.GetComponent<NetworkIdentity>())
- {
- Debug.LogError($"Prefab {newGameObject} cannot be added as spawnable as it doesn't have a NetworkIdentity.");
- return;
- }
- prefab.objectReferenceValue = newGameObject;
- }
- }
- internal void Changed(ReorderableList list)
- {
- EditorUtility.SetDirty(target);
- }
- internal void AddButton(ReorderableList list)
- {
- spawnListProperty.arraySize += 1;
- list.index = spawnListProperty.arraySize - 1;
- SerializedProperty obj = spawnListProperty.GetArrayElementAtIndex(spawnListProperty.arraySize - 1);
- obj.objectReferenceValue = null;
- spawnList.index = spawnList.count - 1;
- Changed(list);
- }
- internal void RemoveButton(ReorderableList list)
- {
- spawnListProperty.DeleteArrayElementAtIndex(spawnList.index);
- if (list.index >= spawnListProperty.arraySize)
- {
- list.index = spawnListProperty.arraySize - 1;
- }
- }
- }
- }
|