using System; using System.Collections.Generic; using Fort23.Mono; using UnityEditor; using UnityEngine; using Object = UnityEngine.Object; namespace Fort23.Editor { [CustomEditor(typeof(ReferenceCollector))] public class ReferenceCollectorEditor : UnityEditor.Editor { private string searchKey { get { return _searchKey; } set { if (_searchKey != value) { _searchKey = value; heroPrefab = referenceCollector.Get(searchKey); } } } private ReferenceCollector referenceCollector; private Object heroPrefab; private string _searchKey = ""; [SerializeField] public bool isAssetBundle; private void DelNullReference() { var dataProperty = serializedObject.FindProperty("data"); for (int i = dataProperty.arraySize - 1; i >= 0; i--) { var gameObjectProperty = dataProperty.GetArrayElementAtIndex(i).FindPropertyRelative("gameObject"); if (gameObjectProperty.objectReferenceValue == null) { dataProperty.DeleteArrayElementAtIndex(i); } } } private void OnEnable() { referenceCollector = (ReferenceCollector)target; } public override void OnInspectorGUI() { //支持撤销,Redo Undo.RecordObject(referenceCollector, "Changed Settings"); var dataProperty = serializedObject.FindProperty("data"); var isAssetBundle = serializedObject.FindProperty("isAssetBundle"); isAssetBundle.boolValue = GUILayout.Toggle(isAssetBundle.boolValue, "是否显示打包文件夹(只有AB包设置文件用得到这个选项)"); GUILayout.BeginHorizontal(); if (GUILayout.Button("添加引用")) { // Guid.NewGuid().GetHashCode().SplitToString() 是新建后默认的key AddReference(dataProperty, Guid.NewGuid().GetHashCode().ToString(), null); } if (GUILayout.Button("全部删除")) { dataProperty.ClearArray(); } if (GUILayout.Button("删除空引用")) { DelNullReference(); } if (GUILayout.Button("排序")) { referenceCollector.Sort(); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); //可以在编辑器中对searchKey进行赋值,只要输入对应的Key值,就可以点后面的删除按钮删除相对应的元素 searchKey = EditorGUILayout.TextField(searchKey); //添加的可以用于选中Object的框,这里的object也是(UnityEngine.Object //第三个参数为是否只能引用scene中的Object EditorGUILayout.ObjectField(heroPrefab, typeof(Object), false); if (GUILayout.Button("删除")) { referenceCollector.Remove(searchKey); heroPrefab = null; } GUILayout.EndHorizontal(); EditorGUILayout.Space(); var delList = new List(); SerializedProperty property; //遍历ReferenceCollector中data list的所有元素,显示在编辑器中 for (int i = referenceCollector.data.Count - 1; i >= 0; i--) { GUILayout.BeginHorizontal(); SerializedProperty rcDataSp = dataProperty.GetArrayElementAtIndex(i); if (rcDataSp == null) { continue; } SerializedProperty listSp = rcDataSp.FindPropertyRelative("isList"); //这里的知识点在ReferenceCollector中有说 if (dataProperty.arraySize > i) { if (isAssetBundle.boolValue) { property = rcDataSp.FindPropertyRelative("isAssetBundle"); property.boolValue = EditorGUILayout.ToggleLeft("文件夹打AB", property.boolValue, GUILayout.Width(100)); listSp.boolValue = EditorGUILayout.ToggleLeft("是否是List", listSp.boolValue, GUILayout.Width(100)); property = rcDataSp.FindPropertyRelative("key"); property.stringValue = EditorGUILayout.TextField(property.stringValue, GUILayout.Width(100)); property = rcDataSp.FindPropertyRelative("gameObject"); property.objectReferenceValue = EditorGUILayout.ObjectField(property.objectReferenceValue, typeof(Object), true); } else { property = rcDataSp.FindPropertyRelative("key"); property.stringValue = EditorGUILayout.TextField(property.stringValue, GUILayout.Width(150)); property = rcDataSp.FindPropertyRelative("gameObject"); property.objectReferenceValue = EditorGUILayout.ObjectField(property.objectReferenceValue, typeof(Object), true); } if (GUILayout.Button("X")) { //将元素添加进删除list delList.Add(i); } } GUILayout.EndHorizontal(); if (listSp.boolValue) { string key = rcDataSp.FindPropertyRelative("key").stringValue; SerializedProperty ListCollectorDatas = rcDataSp.FindPropertyRelative("ListCollectorDatas"); EditorGUILayout.PropertyField(ListCollectorDatas, new GUIContent(key)); } } var eventType = Event.current.type; //在Inspector 窗口上创建区域,向区域拖拽资源对象,获取到拖拽到区域的对象 if (eventType == EventType.DragUpdated || eventType == EventType.DragPerform) { // ShowForHall a copy icon on the drag DragAndDrop.visualMode = DragAndDropVisualMode.Copy; if (eventType == EventType.DragPerform) { DragAndDrop.AcceptDrag(); foreach (var o in DragAndDrop.objectReferences) { AddReference(dataProperty, o.name, o); } } Event.current.Use(); } //遍历删除list,将其删除掉 foreach (var i in delList) { dataProperty.DeleteArrayElementAtIndex(i); } serializedObject.ApplyModifiedProperties(); serializedObject.UpdateIfRequiredOrScript(); } //添加元素 private void AddReference(SerializedProperty dataProperty, string key, Object obj) { int index = dataProperty.arraySize; dataProperty.InsertArrayElementAtIndex(index); var element = dataProperty.GetArrayElementAtIndex(index); element.FindPropertyRelative("key").stringValue = key; element.FindPropertyRelative("gameObject").objectReferenceValue = obj; } } }