164 lines
5.4 KiB
C#
164 lines
5.4 KiB
C#
using UnityEngine;
|
|
using UnityEditor;
|
|
using System;
|
|
using System.Linq;
|
|
using System.Collections.Generic;
|
|
|
|
[CustomEditor(typeof(SOEditorConfig))]
|
|
public class SOEditorConfigEditor : Editor
|
|
{
|
|
private SerializedProperty _typeNamesProp;
|
|
private string _searchText = "";
|
|
|
|
private void OnEnable()
|
|
{
|
|
_typeNamesProp = serializedObject.FindProperty("targetTypeNames");
|
|
}
|
|
|
|
public override void OnInspectorGUI()
|
|
{
|
|
serializedObject.Update();
|
|
|
|
SOEditorConfig config = (SOEditorConfig)target;
|
|
|
|
GUILayout.Label("已管理的 SO 类型:", EditorStyles.boldLabel);
|
|
|
|
// === 1. 绘制已添加的类型列表 ===
|
|
EditorGUILayout.BeginVertical("box");
|
|
for (int i = 0; i < _typeNamesProp.arraySize; i++)
|
|
{
|
|
SerializedProperty prop = _typeNamesProp.GetArrayElementAtIndex(i);
|
|
string typeName = prop.stringValue;
|
|
|
|
EditorGUILayout.BeginHorizontal();
|
|
{
|
|
GUILayout.Label($"{i + 1}. {typeName}", EditorStyles.label);
|
|
|
|
if (GUILayout.Button(EditorGUIUtility.IconContent("TreeEditor.Trash"), EditorStyles.iconButton, GUILayout.Width(25)))
|
|
{
|
|
_typeNamesProp.DeleteArrayElementAtIndex(i);
|
|
break;
|
|
}
|
|
}
|
|
EditorGUILayout.EndHorizontal();
|
|
}
|
|
|
|
if (_typeNamesProp.arraySize == 0)
|
|
{
|
|
GUILayout.Label("暂无类型,请添加", EditorStyles.centeredGreyMiniLabel);
|
|
}
|
|
|
|
EditorGUILayout.EndVertical();
|
|
|
|
GUILayout.Space(10);
|
|
|
|
// === 2. 拖拽区域 (核心修改) ===
|
|
DrawDragDropArea();
|
|
|
|
GUILayout.Space(10);
|
|
|
|
// === 3. 搜索添加 ===
|
|
GUILayout.Label("或者:搜索添加", EditorStyles.boldLabel);
|
|
EditorGUILayout.BeginHorizontal();
|
|
_searchText = EditorGUILayout.TextField(_searchText, EditorStyles.toolbarSearchField);
|
|
if (GUILayout.Button("搜索", GUILayout.Width(60)))
|
|
{
|
|
ShowTypeSelectorMenu(config);
|
|
}
|
|
|
|
EditorGUILayout.EndHorizontal();
|
|
|
|
serializedObject.ApplyModifiedProperties();
|
|
}
|
|
|
|
private void DrawDragDropArea()
|
|
{
|
|
// 绘制一个虚线框区域
|
|
Rect dropArea = GUILayoutUtility.GetRect(0.0f, 60.0f, GUILayout.ExpandWidth(true));
|
|
GUI.Box(dropArea, "\n拖拽文件到这里添加\n(支持 .cs 脚本 或 .asset 资源)", EditorStyles.helpBox);
|
|
|
|
Event evt = Event.current;
|
|
if (evt.type == EventType.DragUpdated || evt.type == EventType.DragPerform)
|
|
{
|
|
if (!dropArea.Contains(evt.mousePosition)) return;
|
|
|
|
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
|
|
|
|
if (evt.type == EventType.DragPerform)
|
|
{
|
|
DragAndDrop.AcceptDrag();
|
|
|
|
foreach (UnityEngine.Object dragged_object in DragAndDrop.objectReferences)
|
|
{
|
|
Type typeToAdd = null;
|
|
|
|
// 情况 A: 拖入的是 .cs 脚本文件
|
|
if (dragged_object is MonoScript script)
|
|
{
|
|
typeToAdd = script.GetClass();
|
|
}
|
|
// 情况 B: 拖入的是 .asset 资源实例 (比如 New Tank.asset)
|
|
else if (dragged_object is ScriptableObject soInstance)
|
|
{
|
|
// 直接获取这个实例的类型
|
|
typeToAdd = soInstance.GetType();
|
|
}
|
|
|
|
// 执行添加逻辑
|
|
if (typeToAdd != null)
|
|
{
|
|
// 过滤掉 Config 本身,防止把自己加进去
|
|
if (typeToAdd == typeof(SOEditorConfig)) continue;
|
|
|
|
if (typeToAdd.IsSubclassOf(typeof(ScriptableObject)))
|
|
{
|
|
AddType(typeToAdd.FullName);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ShowTypeSelectorMenu(SOEditorConfig config)
|
|
{
|
|
GenericMenu menu = new GenericMenu();
|
|
|
|
var allSoTypes = TypeCache.GetTypesDerivedFrom<ScriptableObject>()
|
|
.Where(t => !t.IsAbstract && !t.IsGenericType && !t.Namespace.StartsWith("Unity") && !t.Namespace.StartsWith("UnityEditor"))
|
|
.OrderBy(t => t.Name);
|
|
|
|
foreach (var type in allSoTypes)
|
|
{
|
|
if (!string.IsNullOrEmpty(_searchText) && !type.Name.ToLower().Contains(_searchText.ToLower()))
|
|
continue;
|
|
|
|
string menuPath = string.IsNullOrEmpty(type.Namespace) ? type.Name : $"{type.Namespace}/{type.Name}";
|
|
|
|
menu.AddItem(new GUIContent(menuPath), config.targetTypeNames.Contains(type.FullName), () => { AddType(type.FullName); });
|
|
}
|
|
|
|
menu.ShowAsContext();
|
|
}
|
|
|
|
private void AddType(string typeFullName)
|
|
{
|
|
serializedObject.Update();
|
|
bool exists = false;
|
|
for (int i = 0; i < _typeNamesProp.arraySize; i++)
|
|
{
|
|
if (_typeNamesProp.GetArrayElementAtIndex(i).stringValue == typeFullName)
|
|
{
|
|
exists = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!exists)
|
|
{
|
|
_typeNamesProp.InsertArrayElementAtIndex(_typeNamesProp.arraySize);
|
|
_typeNamesProp.GetArrayElementAtIndex(_typeNamesProp.arraySize - 1).stringValue = typeFullName;
|
|
serializedObject.ApplyModifiedProperties();
|
|
}
|
|
}
|
|
} |