Files
Fishing2/Assets/Scripts/Editor/Preview/PreviewEditWindow.cs
2025-06-25 11:52:30 +08:00

204 lines
6.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace NBF
{
public class PreviewableAssetEditor : EditorWindow
{
private List<GameObject> previewablePrefabs = new List<GameObject>();
private Vector2 scrollPosition;
private int selectedIndex = -1;
private GameObject selectedPrefab;
private Editor prefabEditor;
private SerializedObject serializedObject;
[MenuItem("Tools/Previewable Asset Editor")]
public static void ShowWindow()
{
GetWindow<PreviewableAssetEditor>("Previewable Assets");
}
private void OnEnable()
{
RefreshPrefabList();
}
private void RefreshPrefabList()
{
previewablePrefabs.Clear();
// 查找项目中所有预制体
string[] guids = AssetDatabase.FindAssets("t:Prefab");
foreach (string guid in guids)
{
string path = AssetDatabase.GUIDToAssetPath(guid);
GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);
// 检查预制体是否有 PreviewableAsset 组件
if (prefab.GetComponent<PreviewableAsset>() != null)
{
previewablePrefabs.Add(prefab);
}
}
// 按名称排序
previewablePrefabs = previewablePrefabs.OrderBy(p => p.name).ToList();
}
private void OnGUI()
{
EditorGUILayout.BeginHorizontal();
// 左侧列表
DrawPrefabList();
// 右侧操作区域
DrawOperationArea();
EditorGUILayout.EndHorizontal();
}
private void DrawPrefabList()
{
EditorGUILayout.BeginVertical(GUILayout.Width(250));
EditorGUILayout.LabelField("Previewable Assets", EditorStyles.boldLabel);
EditorGUILayout.Space();
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition, "box");
for (int i = 0; i < previewablePrefabs.Count; i++)
{
var prefab = previewablePrefabs[i];
bool isSelected = i == selectedIndex;
EditorGUILayout.BeginHorizontal();
// 使用 toggle 样式按钮来模拟选择
if (GUILayout.Toggle(isSelected, prefab.name, "Button", GUILayout.Height(20)))
{
if (!isSelected)
{
selectedIndex = i;
selectedPrefab = prefab;
CreatePrefabEditor();
}
}
EditorGUILayout.EndHorizontal();
}
EditorGUILayout.EndScrollView();
// 刷新按钮
if (GUILayout.Button("Refresh List"))
{
RefreshPrefabList();
selectedIndex = -1;
selectedPrefab = null;
prefabEditor = null;
}
EditorGUILayout.EndVertical();
}
private void DrawOperationArea()
{
EditorGUILayout.BeginVertical(GUILayout.ExpandWidth(true));
if (selectedPrefab == null)
{
EditorGUILayout.HelpBox("Select a prefab from the list to edit its PreviewableAsset properties.",
MessageType.Info);
}
else
{
EditorGUILayout.LabelField("Editing: " + selectedPrefab.name, EditorStyles.boldLabel);
EditorGUILayout.Space();
// 显示预制体预览
if (prefabEditor != null)
{
prefabEditor.OnPreviewGUI(GUILayoutUtility.GetRect(100, 100), EditorStyles.helpBox);
}
EditorGUILayout.Space();
// 显示 PreviewableAsset 属性
var previewableAsset = selectedPrefab.GetComponent<PreviewableAsset>();
if (previewableAsset != null)
{
if (serializedObject == null || serializedObject.targetObject != previewableAsset)
{
serializedObject = new SerializedObject(previewableAsset);
}
serializedObject.Update();
// 自动绘制所有序列化字段
SerializedProperty prop = serializedObject.GetIterator();
bool enterChildren = true;
while (prop.NextVisible(enterChildren))
{
enterChildren = false;
if (prop.name == "m_Script") continue; // 跳过脚本引用
EditorGUILayout.PropertyField(prop, true);
}
serializedObject.ApplyModifiedProperties();
EditorGUILayout.Space();
// 保存按钮
if (GUILayout.Button("Save Changes", GUILayout.Height(30)))
{
SaveChanges();
}
}
else
{
EditorGUILayout.HelpBox("Selected prefab no longer has a PreviewableAsset component.",
MessageType.Warning);
}
}
EditorGUILayout.EndVertical();
}
private void CreatePrefabEditor()
{
if (prefabEditor != null)
{
DestroyImmediate(prefabEditor);
}
prefabEditor = Editor.CreateEditor(selectedPrefab);
}
private void SaveChanges()
{
if (selectedPrefab != null)
{
// 标记预制体为脏以便保存
EditorUtility.SetDirty(selectedPrefab);
// 保存预制体
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
Debug.Log("Prefab " + selectedPrefab.name + " saved successfully.");
}
}
private void OnDisable()
{
if (prefabEditor != null)
{
DestroyImmediate(prefabEditor);
}
}
}
}