389 lines
12 KiB
C#
389 lines
12 KiB
C#
using UnityEngine;
|
|
using UnityEditor;
|
|
using System.Collections.Generic;
|
|
using NBC;
|
|
using NBF;
|
|
|
|
public class RuntimePreviewEditor : EditorWindow
|
|
{
|
|
// 运行时实例引用
|
|
private GameObject runtimeInstance;
|
|
private PreviewableAsset runtimePreviewableAsset;
|
|
|
|
// 预制体列表
|
|
private List<GameObject> prefabList = new List<GameObject>();
|
|
private int selectedPrefabIndex = -1;
|
|
private Vector2 scrollPosition;
|
|
|
|
// 预览控制
|
|
private bool isPreviewing = false;
|
|
|
|
private PreviewPanel _previewPanel;
|
|
|
|
[MenuItem("Tools/Runtime Preview Editor")]
|
|
public static void ShowWindow()
|
|
{
|
|
GetWindow<RuntimePreviewEditor>("Runtime Preview");
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
EditorApplication.playModeStateChanged -= OnPlayModeStateChanged;
|
|
ClearRuntimeInstance();
|
|
}
|
|
|
|
private void OnPlayModeStateChanged(PlayModeStateChange state)
|
|
{
|
|
if (state == PlayModeStateChange.ExitingPlayMode)
|
|
{
|
|
ClearRuntimeInstance();
|
|
isPreviewing = false;
|
|
}
|
|
}
|
|
|
|
private void RefreshPrefabList()
|
|
{
|
|
Debug.LogError("重新加载所有预制体==");
|
|
prefabList.Clear();
|
|
|
|
string[] guids = AssetDatabase.FindAssets("t:Prefab");
|
|
foreach (string guid in guids)
|
|
{
|
|
string path = AssetDatabase.GUIDToAssetPath(guid);
|
|
GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);
|
|
|
|
if (prefab.GetComponent<PreviewableAsset>() != null)
|
|
{
|
|
prefabList.Add(prefab);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OnGUI()
|
|
{
|
|
EditorGUILayout.BeginHorizontal();
|
|
|
|
// 左侧预制体列表
|
|
DrawPrefabList();
|
|
|
|
// 右侧预览和操作区域
|
|
DrawPreviewArea();
|
|
|
|
EditorGUILayout.EndHorizontal();
|
|
}
|
|
|
|
private void DrawPrefabList()
|
|
{
|
|
EditorGUILayout.BeginVertical(GUILayout.Width(250));
|
|
|
|
EditorGUILayout.LabelField("Available Prefabs", EditorStyles.boldLabel);
|
|
EditorGUILayout.Space();
|
|
|
|
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
|
|
|
|
for (int i = 0; i < prefabList.Count; i++)
|
|
{
|
|
bool isSelected = i == selectedPrefabIndex;
|
|
if (GUILayout.Toggle(isSelected, prefabList[i].name, "Button"))
|
|
{
|
|
if (!isSelected)
|
|
{
|
|
selectedPrefabIndex = i;
|
|
if (Application.isPlaying)
|
|
{
|
|
LoadRuntimeInstance();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
EditorGUILayout.EndScrollView();
|
|
|
|
if (GUILayout.Button("Refresh List"))
|
|
{
|
|
RefreshPrefabList();
|
|
}
|
|
|
|
EditorGUILayout.EndVertical();
|
|
}
|
|
|
|
private void DrawPreviewArea()
|
|
{
|
|
EditorGUILayout.BeginVertical(GUILayout.ExpandWidth(true));
|
|
|
|
if (!Application.isPlaying)
|
|
{
|
|
EditorGUILayout.HelpBox("运行模式才可以编辑.", MessageType.Info);
|
|
EditorGUILayout.EndVertical();
|
|
return;
|
|
}
|
|
|
|
if (selectedPrefabIndex == -1)
|
|
{
|
|
EditorGUILayout.HelpBox("未选中预制体", MessageType.Info);
|
|
EditorGUILayout.EndVertical();
|
|
return;
|
|
}
|
|
|
|
GUILayout.BeginHorizontal();
|
|
if (GUILayout.Button("上一个"))
|
|
{
|
|
if (selectedPrefabIndex > 0)
|
|
{
|
|
selectedPrefabIndex--;
|
|
RefreshRuntimeInstance();
|
|
// EnsureSelectionVisible();
|
|
}
|
|
}
|
|
|
|
GUILayout.Space(20);
|
|
if (GUILayout.Button("下一个"))
|
|
{
|
|
if (selectedPrefabIndex < prefabList.Count - 1)
|
|
{
|
|
selectedPrefabIndex++;
|
|
RefreshRuntimeInstance();
|
|
// EnsureSelectionVisible();
|
|
}
|
|
}
|
|
|
|
GUILayout.EndHorizontal();
|
|
|
|
|
|
var selectedPrefab = prefabList[selectedPrefabIndex];
|
|
EditorGUILayout.LabelField("当前预览: " + selectedPrefab.name, EditorStyles.boldLabel);
|
|
|
|
// 预览控制按钮
|
|
EditorGUILayout.BeginHorizontal();
|
|
if (GUILayout.Button(isPreviewing ? "停止预览" : "开始预览"))
|
|
{
|
|
TogglePreview();
|
|
}
|
|
|
|
if (isPreviewing && GUILayout.Button("刷新实例"))
|
|
{
|
|
RefreshRuntimeInstance();
|
|
}
|
|
|
|
EditorGUILayout.EndHorizontal();
|
|
|
|
// 运行时实例预览和编辑
|
|
if (isPreviewing && runtimeInstance != null && runtimePreviewableAsset)
|
|
{
|
|
EditorGUILayout.Space();
|
|
EditorGUILayout.LabelField("Transform Properties", EditorStyles.boldLabel);
|
|
|
|
// 记录变化开始
|
|
EditorGUI.BeginChangeCheck();
|
|
|
|
// 编辑Transform
|
|
var newPosition = EditorGUILayout.Vector3Field("位置", runtimeInstance.transform.localPosition);
|
|
var newRotation = EditorGUILayout.Vector3Field("旋转", runtimeInstance.transform.parent.localEulerAngles);
|
|
var newScale = EditorGUILayout.Vector3Field("形变", runtimeInstance.transform.localScale);
|
|
|
|
|
|
// var canZoom = EditorGUILayout.Toggle("允许缩放", runtimePreviewableAsset.canZoom);
|
|
// if (canZoom)
|
|
// {
|
|
// runtimePreviewableAsset.zoom = EditorGUILayout.Vector3Field("放大缩小配置", runtimePreviewableAsset.zoom);
|
|
// }
|
|
//
|
|
// var canPan = EditorGUILayout.Toggle("允许拖动", runtimePreviewableAsset.canPan);
|
|
// if (canPan)
|
|
// {
|
|
// runtimePreviewableAsset.pan = EditorGUILayout.RectField("拖动配置", runtimePreviewableAsset.pan);
|
|
// }
|
|
//
|
|
// // 应用Transform修改
|
|
// if (EditorGUI.EndChangeCheck())
|
|
// {
|
|
// runtimeInstance.transform.localPosition = new Vector3(newPosition.x, newPosition.y, 0);
|
|
// runtimeInstance.transform.parent.localEulerAngles = newRotation;
|
|
// runtimeInstance.transform.localScale = newScale;
|
|
//
|
|
// runtimePreviewableAsset.position = new Vector3(newPosition.x, newPosition.y, 0);
|
|
// runtimePreviewableAsset.rotation = newRotation;
|
|
// runtimePreviewableAsset.scale = newScale;
|
|
// runtimePreviewableAsset.canZoom = canZoom;
|
|
// runtimePreviewableAsset.canPan = canPan;
|
|
//
|
|
//
|
|
// var pos = runtimeInstance.transform.parent.localPosition;
|
|
// if (canZoom)
|
|
// {
|
|
// if (!Mathf.Approximately(pos.z, runtimePreviewableAsset.zoom.z))
|
|
// {
|
|
// runtimeInstance.transform.parent.localPosition =
|
|
// new Vector3(pos.x, pos.y, runtimePreviewableAsset.zoom.z);
|
|
// }
|
|
// }
|
|
// else
|
|
// {
|
|
// runtimeInstance.transform.parent.localPosition = new Vector3(pos.x, pos.y, 0);
|
|
// }
|
|
//
|
|
// // if (canZoom)
|
|
// // {
|
|
// // if (!Mathf.Approximately(runtimeInstance.transform.localPosition.z,
|
|
// // runtimePreviewableAsset.zoom.z))
|
|
// // {
|
|
// // var pos = runtimeInstance.transform.parent.localPosition;
|
|
// // runtimeInstance.transform.parent.localPosition =
|
|
// // new Vector3(pos.x, pos.y, runtimePreviewableAsset.zoom.z);
|
|
// // }
|
|
// // }
|
|
// // else
|
|
// // {
|
|
// // runtimeInstance.transform.parent.localPosition = Vector3.zero;
|
|
// // }
|
|
// }
|
|
|
|
EditorGUILayout.Space();
|
|
|
|
// 保存到预制体按钮
|
|
if (GUILayout.Button("保存到预制体", GUILayout.Height(30)))
|
|
{
|
|
SaveChangesToPrefab();
|
|
}
|
|
|
|
if (GUILayout.Button("生成ICON", GUILayout.Height(30)))
|
|
{
|
|
// SaveChangesToPrefab();
|
|
}
|
|
}
|
|
|
|
EditorGUILayout.EndVertical();
|
|
}
|
|
|
|
private void TogglePreview()
|
|
{
|
|
isPreviewing = !isPreviewing;
|
|
|
|
if (isPreviewing)
|
|
{
|
|
_previewPanel = UI.Inst.GetUI<PreviewPanel>();
|
|
if (_previewPanel == null)
|
|
{
|
|
isPreviewing = false;
|
|
Debug.LogError("显示UI面包未打开");
|
|
}
|
|
}
|
|
|
|
|
|
if (isPreviewing)
|
|
{
|
|
LoadRuntimeInstance();
|
|
}
|
|
else
|
|
{
|
|
ClearRuntimeInstance();
|
|
}
|
|
}
|
|
|
|
private void LoadRuntimeInstance()
|
|
{
|
|
ClearRuntimeInstance();
|
|
|
|
if (selectedPrefabIndex == -1 || !Application.isPlaying) return;
|
|
|
|
var prefab = prefabList[selectedPrefabIndex];
|
|
|
|
// 调用自定义实例化方法
|
|
// runtimeInstance = Instantiate(prefab);
|
|
// runtimeInstance.hideFlags = HideFlags.DontSave;
|
|
|
|
if (_previewPanel == null) return;
|
|
|
|
// runtimeInstance = _previewPanel.LoadModel(prefab);
|
|
runtimeInstance.hideFlags = HideFlags.DontSave;
|
|
|
|
if (runtimeInstance != null)
|
|
{
|
|
runtimePreviewableAsset = runtimeInstance.GetComponent<PreviewableAsset>();
|
|
Selection.activeGameObject = runtimeInstance;
|
|
}
|
|
}
|
|
|
|
private void RefreshRuntimeInstance()
|
|
{
|
|
if (selectedPrefabIndex == -1 || !Application.isPlaying) return;
|
|
|
|
ClearRuntimeInstance();
|
|
LoadRuntimeInstance();
|
|
}
|
|
|
|
private void SaveChangesToPrefab()
|
|
{
|
|
if (selectedPrefabIndex == -1 || runtimeInstance == null) return;
|
|
|
|
var prefab = prefabList[selectedPrefabIndex];
|
|
|
|
var previewableAsset = prefab.GetComponent<PreviewableAsset>();
|
|
if (previewableAsset && runtimePreviewableAsset)
|
|
{
|
|
// previewableAsset.position = runtimePreviewableAsset.position;
|
|
// previewableAsset.rotation = runtimePreviewableAsset.rotation;
|
|
// previewableAsset.scale = runtimePreviewableAsset.scale;
|
|
// previewableAsset.canPan = runtimePreviewableAsset.canPan;
|
|
// previewableAsset.canZoom = runtimePreviewableAsset.canZoom;
|
|
// previewableAsset.zoom = runtimePreviewableAsset.zoom;
|
|
// previewableAsset.pan = runtimePreviewableAsset.pan;
|
|
}
|
|
|
|
EditorUtility.SetDirty(prefab);
|
|
AssetDatabase.Refresh();
|
|
// // 默认实现 - 直接修改预制体
|
|
// PrefabUtility.SaveAsPrefabAsset(runtimeInstance, AssetDatabase.GetAssetPath(prefab));
|
|
// AssetDatabase.Refresh();
|
|
|
|
Debug.Log("Changes saved to prefab: " + prefab.name);
|
|
}
|
|
|
|
private void ClearRuntimeInstance()
|
|
{
|
|
if (runtimeInstance != null)
|
|
{
|
|
if (Application.isPlaying)
|
|
{
|
|
Destroy(runtimeInstance);
|
|
}
|
|
else
|
|
{
|
|
DestroyImmediate(runtimeInstance);
|
|
}
|
|
}
|
|
|
|
runtimeInstance = null;
|
|
runtimePreviewableAsset = null;
|
|
}
|
|
|
|
// // 确保选中项在可视区域内
|
|
// private void EnsureSelectionVisible()
|
|
// {
|
|
// // 计算选中项的大概位置
|
|
// float itemHeight = 24; // 每个列表项的大约高度
|
|
// float visibleHeight = position.height - 100; // 可视区域的大约高度
|
|
//
|
|
// // 计算选中项应该在的滚动位置范围
|
|
// float targetMin = selectedPrefabIndex * itemHeight;
|
|
// float targetMax = targetMin + itemHeight;
|
|
//
|
|
// // 调整滚动位置
|
|
// if (scrollPosition.y > targetMin)
|
|
// {
|
|
// scrollPosition.y = targetMin;
|
|
// }
|
|
// else if (scrollPosition.y + visibleHeight < targetMax)
|
|
// {
|
|
// scrollPosition.y = targetMax - visibleHeight;
|
|
// }
|
|
//
|
|
// // 重绘界面
|
|
// Repaint();
|
|
// }
|
|
} |