chore(huoshang): 移除 SOEditorTool 插件,SellSystem 重命名为 SaleSystem
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 203b6470a52cede43824c2b766b89464
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1b33e012f04c4b66890fad3401d1abd1
|
||||
timeCreated: 1765258694
|
||||
@@ -1,11 +0,0 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class CNNameAttribute : PropertyAttribute
|
||||
{
|
||||
public string Name;
|
||||
|
||||
public CNNameAttribute(string name)
|
||||
{
|
||||
this.Name = name;
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 251a6a4e8eda4e9bbfa088b9a34b0e7b
|
||||
timeCreated: 1765258702
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 108f43113da2467789e5bef2327add79
|
||||
timeCreated: 1765215242
|
||||
@@ -1,39 +0,0 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
|
||||
[CustomPropertyDrawer(typeof(CNNameAttribute))]
|
||||
public class CNNameDrawer : PropertyDrawer
|
||||
{
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
// 1. 获取特性中的中文名
|
||||
CNNameAttribute attr = (CNNameAttribute)attribute;
|
||||
|
||||
// 2. 替换原本的 Label
|
||||
GUIContent newLabel = new GUIContent(attr.Name, label.tooltip);
|
||||
|
||||
// 3. 绘制属性(使用中文名)
|
||||
EditorGUI.PropertyField(position, property, newLabel, true);
|
||||
|
||||
// 4. 绘制变量原名(灰色小字,显示在 Label 区域的右侧)
|
||||
// 计算 Label 的区域
|
||||
float labelWidth = EditorGUIUtility.labelWidth;
|
||||
Rect labelRect = new Rect(position.x, position.y, labelWidth, position.height);
|
||||
|
||||
// 设置小字样式
|
||||
GUIStyle subStyle = new GUIStyle(EditorStyles.miniLabel);
|
||||
subStyle.normal.textColor = new Color(0.5f, 0.5f, 0.5f, 0.6f); // 半透明灰色
|
||||
subStyle.alignment = TextAnchor.MiddleRight; // 右对齐
|
||||
subStyle.fontSize = 9;
|
||||
subStyle.padding = new RectOffset(0, 2, 0, 0); //稍微留点边距
|
||||
|
||||
// 绘制变量名 (例如: "maxHP")
|
||||
GUI.Label(labelRect, property.name, subStyle);
|
||||
}
|
||||
|
||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
||||
{
|
||||
return EditorGUI.GetPropertyHeight(property, label);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0c0f975bcc144b9187928b83dc9aaeac
|
||||
timeCreated: 1765258716
|
||||
@@ -1,164 +0,0 @@
|
||||
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 && !string.IsNullOrEmpty(t.Namespace) && !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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 45f4877471fd47efb465a700a6869eb4
|
||||
timeCreated: 1765219950
|
||||
@@ -1,428 +0,0 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
public class UniversalSOManager : EditorWindow
|
||||
{
|
||||
// === 布局常量 ===
|
||||
private const float SIDEBAR_WIDTH = 160f;
|
||||
private const float ASSET_LIST_WIDTH = 220f;
|
||||
|
||||
// === 核心数据 ===
|
||||
private SOEditorConfig _config;
|
||||
private Type _selectedType; // 现在直接存 Type,不再存 MonoScript
|
||||
|
||||
// === 列表与编辑 ===
|
||||
private List<ScriptableObject> _assetList = new List<ScriptableObject>();
|
||||
private ScriptableObject _selectedAsset;
|
||||
private Editor _cachedEditor;
|
||||
|
||||
// === 状态 ===
|
||||
private string _searchRootPath = "Assets/SOGameData";
|
||||
private Vector2 _scrollPosTypes;
|
||||
private Vector2 _scrollPosAssets;
|
||||
private Vector2 _scrollPosInspector;
|
||||
private string _searchString = "";
|
||||
private string _newAssetName = "";
|
||||
|
||||
[MenuItem("Tools/万能SO编辑器 (Universal SO Manager)")]
|
||||
public static void ShowWindow()
|
||||
{
|
||||
GetWindow<UniversalSOManager>("SO Manager");
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
string configPath = EditorPrefs.GetString("UniversalSOManager_ConfigPath", "");
|
||||
if (!string.IsNullOrEmpty(configPath))
|
||||
{
|
||||
_config = AssetDatabase.LoadAssetAtPath<SOEditorConfig>(configPath);
|
||||
}
|
||||
|
||||
// 加载保存的资源路径
|
||||
_searchRootPath = EditorPrefs.GetString("UniversalSOManager_SearchRootPath", "Assets/SOGameData");
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (_cachedEditor != null) DestroyImmediate(_cachedEditor);
|
||||
if (_config != null)
|
||||
{
|
||||
EditorPrefs.SetString("UniversalSOManager_ConfigPath", AssetDatabase.GetAssetPath(_config));
|
||||
}
|
||||
|
||||
// 保存资源路径
|
||||
EditorPrefs.SetString("UniversalSOManager_SearchRootPath", _searchRootPath);
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
DrawTopGlobalBar();
|
||||
|
||||
if (_config == null)
|
||||
{
|
||||
DrawEmptyState();
|
||||
return;
|
||||
}
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
DrawSidebar();
|
||||
|
||||
EditorGUILayout.BeginVertical();
|
||||
{
|
||||
DrawTypeOperationHeader();
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
DrawAssetList();
|
||||
DrawInspector();
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// UI 绘制函数
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
private void DrawTopGlobalBar()
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal("box", GUILayout.Height(30));
|
||||
{
|
||||
GUILayout.Label("资源路径:", GUILayout.Width(60));
|
||||
_searchRootPath = EditorGUILayout.TextField(_searchRootPath, GUILayout.Width(150));
|
||||
if (GUILayout.Button("...", EditorStyles.miniButton, GUILayout.Width(25)))
|
||||
{
|
||||
string path = EditorUtility.OpenFolderPanel("选择根目录", Application.dataPath, "");
|
||||
if (!string.IsNullOrEmpty(path) && path.StartsWith(Application.dataPath))
|
||||
{
|
||||
_searchRootPath = "Assets" + path.Substring(Application.dataPath.Length);
|
||||
RefreshAssetList();
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.Space(20);
|
||||
|
||||
GUILayout.Label("Config文件:", GUILayout.Width(70));
|
||||
EditorGUI.BeginChangeCheck();
|
||||
_config = (SOEditorConfig)EditorGUILayout.ObjectField(_config, typeof(SOEditorConfig), false, GUILayout.Width(200));
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
_selectedType = null;
|
||||
_assetList.Clear();
|
||||
_selectedAsset = null;
|
||||
GUIUtility.ExitGUI();
|
||||
}
|
||||
|
||||
// 快捷编辑 Config 按钮
|
||||
if (_config != null)
|
||||
{
|
||||
if (GUILayout.Button("编辑Config", EditorStyles.miniButton, GUILayout.Width(80)))
|
||||
{
|
||||
Selection.activeObject = _config;
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
if (GUILayout.Button("强制刷新", EditorStyles.toolbarButton, GUILayout.Width(80)))
|
||||
{
|
||||
AssetDatabase.Refresh();
|
||||
RefreshAssetList();
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
private void DrawSidebar()
|
||||
{
|
||||
EditorGUILayout.BeginVertical("box", GUILayout.Width(SIDEBAR_WIDTH), GUILayout.ExpandHeight(true));
|
||||
|
||||
GUILayout.Label("SO 种类", EditorStyles.boldLabel);
|
||||
GUILayout.Space(5);
|
||||
|
||||
_scrollPosTypes = EditorGUILayout.BeginScrollView(_scrollPosTypes);
|
||||
|
||||
if (_config != null && _config.targetTypeNames != null)
|
||||
{
|
||||
foreach (var typeName in _config.targetTypeNames)
|
||||
{
|
||||
// 解析类型
|
||||
Type type = GetTypeByName(typeName);
|
||||
|
||||
if (type == null)
|
||||
{
|
||||
// 类型丢失(可能代码改名了)
|
||||
GUI.color = Color.red;
|
||||
GUILayout.Label($"丢失: {typeName}");
|
||||
GUI.color = Color.white;
|
||||
continue;
|
||||
}
|
||||
|
||||
bool isSelected = (_selectedType == type);
|
||||
if (isSelected) GUI.backgroundColor = new Color(0.6f, 0.8f, 1f);
|
||||
|
||||
// 使用短名显示,但在 Tooltip 显示全名
|
||||
if (GUILayout.Button(new GUIContent(type.Name, type.FullName), EditorStyles.miniButton, GUILayout.Height(28)))
|
||||
{
|
||||
SelectType(type);
|
||||
}
|
||||
|
||||
GUI.backgroundColor = Color.white;
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.EndScrollView();
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
private void DrawTypeOperationHeader()
|
||||
{
|
||||
EditorGUILayout.BeginVertical("box", GUILayout.Height(60), GUILayout.ExpandWidth(true));
|
||||
|
||||
string title = _selectedType != null ? _selectedType.Name : "请选择种类";
|
||||
GUILayout.Label($"当前操作: {title}", EditorStyles.boldLabel);
|
||||
|
||||
GUILayout.Space(5);
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
GUILayout.Label("搜索:", GUILayout.Width(40));
|
||||
string newSearch = EditorGUILayout.TextField(_searchString, EditorStyles.toolbarSearchField, GUILayout.Width(200));
|
||||
if (newSearch != _searchString)
|
||||
{
|
||||
_searchString = newSearch;
|
||||
RefreshAssetList();
|
||||
}
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
GUILayout.Label("新名称:", GUILayout.Width(50));
|
||||
_newAssetName = EditorGUILayout.TextField(_newAssetName, GUILayout.Width(150));
|
||||
|
||||
EditorGUI.BeginDisabledGroup(_selectedType == null);
|
||||
if (GUILayout.Button("新增 (Create)", EditorStyles.miniButtonRight, GUILayout.Width(100)))
|
||||
{
|
||||
CreateAsset();
|
||||
}
|
||||
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
private void DrawAssetList()
|
||||
{
|
||||
EditorGUILayout.BeginVertical("box", GUILayout.Width(ASSET_LIST_WIDTH), GUILayout.ExpandHeight(true));
|
||||
|
||||
GUILayout.Label("资源列表", EditorStyles.miniLabel);
|
||||
|
||||
_scrollPosAssets = EditorGUILayout.BeginScrollView(_scrollPosAssets);
|
||||
|
||||
if (_assetList != null)
|
||||
{
|
||||
for (int i = 0; i < _assetList.Count; i++)
|
||||
{
|
||||
var asset = _assetList[i];
|
||||
if (asset == null) continue;
|
||||
|
||||
EditorGUILayout.BeginHorizontal("box");
|
||||
{
|
||||
if (_selectedAsset == asset) GUI.backgroundColor = Color.green;
|
||||
|
||||
if (GUILayout.Button(asset.name, EditorStyles.label, GUILayout.Height(22)))
|
||||
{
|
||||
SelectAsset(asset);
|
||||
}
|
||||
|
||||
GUI.backgroundColor = Color.white;
|
||||
|
||||
if (GUILayout.Button(EditorGUIUtility.IconContent("d_ViewToolOrbit"), EditorStyles.iconButton, GUILayout.Width(22)))
|
||||
EditorGUIUtility.PingObject(asset);
|
||||
|
||||
if (GUILayout.Button(EditorGUIUtility.IconContent("d_TreeEditor.Duplicate"), EditorStyles.iconButton, GUILayout.Width(22)))
|
||||
DuplicateAsset(asset);
|
||||
|
||||
if (GUILayout.Button(EditorGUIUtility.IconContent("TreeEditor.Trash"), EditorStyles.iconButton, GUILayout.Width(22)))
|
||||
{
|
||||
if (EditorUtility.DisplayDialog("删除确认", $"确定删除 {asset.name} 吗?", "删除", "取消"))
|
||||
{
|
||||
DeleteAsset(asset);
|
||||
GUIUtility.ExitGUI();
|
||||
}
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.EndScrollView();
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
private void DrawInspector()
|
||||
{
|
||||
EditorGUILayout.BeginVertical("box", GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));
|
||||
|
||||
if (_selectedAsset != null)
|
||||
{
|
||||
GUILayout.Label("属性编辑", EditorStyles.boldLabel);
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.Label("文件名:", GUILayout.Width(50));
|
||||
string newName = EditorGUILayout.DelayedTextField(_selectedAsset.name);
|
||||
if (newName != _selectedAsset.name) RenameAsset(_selectedAsset, newName);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.Space(10);
|
||||
|
||||
_scrollPosInspector = EditorGUILayout.BeginScrollView(_scrollPosInspector);
|
||||
|
||||
if (_cachedEditor == null || _cachedEditor.target != _selectedAsset)
|
||||
{
|
||||
if (_cachedEditor != null) DestroyImmediate(_cachedEditor);
|
||||
_cachedEditor = Editor.CreateEditor(_selectedAsset);
|
||||
}
|
||||
|
||||
if (_cachedEditor != null)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
_cachedEditor.OnInspectorGUI();
|
||||
if (EditorGUI.EndChangeCheck()) EditorUtility.SetDirty(_selectedAsset);
|
||||
}
|
||||
|
||||
EditorGUILayout.EndScrollView();
|
||||
}
|
||||
else
|
||||
{
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.Label("<< 请选择资源", EditorStyles.centeredGreyMiniLabel);
|
||||
GUILayout.FlexibleSpace();
|
||||
}
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
private void DrawEmptyState()
|
||||
{
|
||||
EditorGUILayout.BeginVertical();
|
||||
GUILayout.FlexibleSpace();
|
||||
EditorGUILayout.HelpBox("请在顶部指定一个 SOEditorConfig 配置文件。", MessageType.Info);
|
||||
GUILayout.FlexibleSpace();
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 逻辑处理
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
// 辅助:从字符串获取类型 (遍历所有程序集)
|
||||
private Type GetTypeByName(string fullName)
|
||||
{
|
||||
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
var type = assembly.GetType(fullName);
|
||||
if (type != null) return type;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void SelectType(Type type)
|
||||
{
|
||||
_selectedType = type;
|
||||
_selectedAsset = null;
|
||||
_newAssetName = "New " + type.Name;
|
||||
RefreshAssetList();
|
||||
}
|
||||
|
||||
private void SelectAsset(ScriptableObject asset)
|
||||
{
|
||||
_selectedAsset = asset;
|
||||
GUI.FocusControl(null);
|
||||
}
|
||||
|
||||
private void RefreshAssetList()
|
||||
{
|
||||
if (_selectedType == null) return;
|
||||
_assetList.Clear();
|
||||
|
||||
// 查找资源
|
||||
string[] guids = AssetDatabase.FindAssets($"t:{_selectedType.Name}", new[] { _searchRootPath });
|
||||
|
||||
foreach (var guid in guids)
|
||||
{
|
||||
string path = AssetDatabase.GUIDToAssetPath(guid);
|
||||
var asset = AssetDatabase.LoadAssetAtPath<ScriptableObject>(path);
|
||||
|
||||
// 严格类型检查 (支持继承)
|
||||
if (asset != null && _selectedType.IsAssignableFrom(asset.GetType()))
|
||||
{
|
||||
if (string.IsNullOrEmpty(_searchString) || asset.name.ToLower().Contains(_searchString.ToLower()))
|
||||
{
|
||||
_assetList.Add(asset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_assetList.Sort((a, b) => string.Compare(a.name, b.name, StringComparison.Ordinal));
|
||||
}
|
||||
|
||||
private void CreateAsset()
|
||||
{
|
||||
if (_selectedType == null) return;
|
||||
|
||||
string targetFolder = $"{_searchRootPath}/{_selectedType.Name}";
|
||||
if (!AssetDatabase.IsValidFolder(targetFolder))
|
||||
{
|
||||
if (AssetDatabase.IsValidFolder(_searchRootPath))
|
||||
AssetDatabase.CreateFolder(_searchRootPath, _selectedType.Name);
|
||||
else
|
||||
targetFolder = _searchRootPath;
|
||||
}
|
||||
|
||||
string fullPath = $"{targetFolder}/{_newAssetName}.asset";
|
||||
fullPath = AssetDatabase.GenerateUniqueAssetPath(fullPath);
|
||||
|
||||
var instance = ScriptableObject.CreateInstance(_selectedType);
|
||||
AssetDatabase.CreateAsset(instance, fullPath);
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
RefreshAssetList();
|
||||
SelectAsset(instance);
|
||||
}
|
||||
|
||||
private void DuplicateAsset(ScriptableObject asset)
|
||||
{
|
||||
string path = AssetDatabase.GetAssetPath(asset);
|
||||
string newPath = AssetDatabase.GenerateUniqueAssetPath(path);
|
||||
AssetDatabase.CopyAsset(path, newPath);
|
||||
AssetDatabase.SaveAssets();
|
||||
RefreshAssetList();
|
||||
}
|
||||
|
||||
private void DeleteAsset(ScriptableObject asset)
|
||||
{
|
||||
string path = AssetDatabase.GetAssetPath(asset);
|
||||
AssetDatabase.DeleteAsset(path);
|
||||
AssetDatabase.SaveAssets();
|
||||
if (_selectedAsset == asset) _selectedAsset = null;
|
||||
RefreshAssetList();
|
||||
}
|
||||
|
||||
private void RenameAsset(ScriptableObject asset, string newName)
|
||||
{
|
||||
string path = AssetDatabase.GetAssetPath(asset);
|
||||
AssetDatabase.RenameAsset(path, newName);
|
||||
AssetDatabase.SaveAssets();
|
||||
RefreshAssetList();
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 70dc192513964637860b748b8957f0f6
|
||||
timeCreated: 1765215245
|
||||
@@ -1,9 +0,0 @@
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
|
||||
[CreateAssetMenu(fileName = "SOEditorConfig", menuName = "Tools/SO编辑器配置 (Config)")]
|
||||
public class SOEditorConfig : ScriptableObject
|
||||
{
|
||||
// 存储类型的全名 (例如 "MyGame.TankEngine")
|
||||
public List<string> targetTypeNames = new List<string>();
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b9d2ad94e1454d91833b3134b5c927bd
|
||||
timeCreated: 1765218978
|
||||
@@ -2436,7 +2436,7 @@ GameObject:
|
||||
m_Component:
|
||||
- component: {fileID: 429189693013891242}
|
||||
m_Layer: 0
|
||||
m_Name: SellSystem
|
||||
m_Name: SaleSystem
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
+5657
-3139
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
# CLAUDE.md
|
||||
<!-- # CLAUDE.md
|
||||
|
||||
Claude Code 与 Cursor 的项目上下文,对话开始时自动加载。
|
||||
|
||||
@@ -171,4 +171,4 @@ Assets\Open C# Project.regenerate-sln.bat
|
||||
- 火山语言粒子是核心玩法,改动需保持情绪表达逻辑
|
||||
- Web 原型仅供验证,正式实现用 Unity/C#
|
||||
- 保持 Windows 与 WebGL 兼容
|
||||
- **开发前按需读 `Docs/` 下对应索引,避免与设计偏离**
|
||||
- **开发前按需读 `Docs/` 下对应索引,避免与设计偏离** -->
|
||||
|
||||
Reference in New Issue
Block a user