NLDClient-yudde/ProjectNLD/Assets/Editor/Scene/PostProcessInstructorInspec...

119 lines
4.9 KiB
C#
Raw Normal View History

2024-01-16 14:23:05 +08:00
using Sirenix.OdinInspector.Editor;
using UnityEditor;
2025-04-07 14:18:07 +08:00
using UnityEditor.SceneManagement;
2024-01-16 14:23:05 +08:00
using UnityEngine;
[CustomEditor(typeof(PostProcessInstructor))]
public class PostProcessInstructorInspector : OdinEditor
{
private PostProcessInstructor Target => target as PostProcessInstructor;
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
2025-04-07 14:18:07 +08:00
EditorGUILayout.Space();
2025-06-16 17:25:12 +08:00
var postProcessInstructors = FindObjectsOfType<PostProcessInstructor>();
2025-04-07 14:18:07 +08:00
using (new EditorGUILayout.HorizontalScope())
2024-01-16 14:23:05 +08:00
{
2025-04-07 14:18:07 +08:00
EditorGUI.BeginDisabledGroup(!Target.enableModelSlicing || Target.ground == null || Target.rootsToSlice == null || Target.rootsToSlice.Count == 0);
if (GUILayout.Button("切割模型"))
{
SliceModels();
}
EditorGUI.EndDisabledGroup();
if (GUILayout.Button("后处理"))
{
ObjectPostProcessorManager.Instance.PostProcess(Target);
}
2025-06-16 17:25:12 +08:00
if (postProcessInstructors.Length > 1 && GUILayout.Button("多节点后处理"))
{
ObjectPostProcessorManager.Instance.PostProcessMore(postProcessInstructors);
}
2024-01-16 14:23:05 +08:00
}
}
2025-04-07 14:18:07 +08:00
/// <summary>
/// 执行模型切割操作
/// </summary>
private void SliceModels()
{
if (!Target.enableModelSlicing || Target.ground == null || Target.rootsToSlice == null || Target.rootsToSlice.Count == 0)
{
Debug.LogWarning("无法执行切割:请确保启用了模型切割功能,并设置了地面和需要切割的模型节点");
return;
}
// 创建SlicerRoot节点作为切割后模型的父节点仅当保留原始模型时使用
GameObject slicerRootObj = null;
Transform slicerRoot = null;
if (Target.preserveOriginalModels)
{
// 保留原始模型时创建SlicerRoot作为切割结果的容器
slicerRootObj = new GameObject("SlicerRoot");
slicerRootObj.transform.parent = Target.combinedObjectsRoot;
slicerRoot = slicerRootObj.transform;
Debug.Log($"创建切割结果根节点: {slicerRootObj.name}");
}
// 预先检查要切割的物体是否是Prefab实例如果是解除Prefab链接
foreach (var root in Target.rootsToSlice)
{
if (root == null) continue;
bool isPrefabInstance = PrefabUtility.IsPartOfPrefabInstance(root.gameObject);
if (isPrefabInstance && !Target.preserveOriginalModels)
{
// 获取Prefab实例的根GameObject
GameObject prefabRoot = PrefabUtility.GetOutermostPrefabInstanceRoot(root.gameObject);
if (prefabRoot != null)
{
Debug.Log($"物体 {root.name} 是Prefab实例的一部分将解除其根节点 {prefabRoot.name} 的Prefab链接");
PrefabUtility.UnpackPrefabInstance(prefabRoot, PrefabUnpackMode.Completely, InteractionMode.AutomatedAction);
}
else
{
Debug.LogWarning($"无法获取物体 {root.name} 的Prefab根节点跳过解除Prefab链接");
}
}
}
// 调用模型切割工具执行切割,根据用户设置决定切割行为
ModelSlicerUtil.Instance.SliceModels(
Target.rootsToSlice,
Target.ground,
Target.sliceMaterial,
Target.slicePlaneDirection,
Target.ignoreObjectBoundsCheck,
Target.sliceAsynchronously,
Target.preserveOriginalModels, // 使用用户的设置,决定是否保留原始模型
slicerRoot, // 当preserveOriginalModels为true时使用SlicerRoot否则为null使用原始节点
Target.saveMeshesToAssets, // 是否保存网格到Assets
Target.meshSavePath, // 网格保存路径
Target.addTimestampToMeshName // 是否添加时间戳
).Wait(); // 同步等待切割完成
var message = Target.preserveOriginalModels ?
"模型切割处理完成切割后的上半部分模型已放置在SlicerRoot节点下原始模型未改变" :
"模型切割处理完成,切割后的上半部分模型已替换原始模型,原始模型已移除";
// 如果保存了网格,添加相关信息
if (Target.saveMeshesToAssets)
{
message += $"\n切割后的网格已保存到路径: Assets/{Target.meshSavePath}";
}
Debug.Log(message);
// 标记场景为已修改,以便保存
EditorUtility.SetDirty(Target.gameObject);
EditorSceneManager.MarkSceneDirty(Target.gameObject.scene);
}
2024-01-16 14:23:05 +08:00
}