171 lines
5.2 KiB
C#
171 lines
5.2 KiB
C#
using System.Collections.Generic;
|
||
using System.IO;
|
||
using UnityEngine;
|
||
using UnityEditor;
|
||
using UnityEditor.SceneManagement;
|
||
using UnityEngine.SceneManagement;
|
||
using UnityEngine.Rendering;
|
||
|
||
/// <summary>
|
||
/// 场景操作工具类
|
||
/// </summary>
|
||
public static class SceneUtils
|
||
{
|
||
/// <summary>
|
||
/// 递归查找子节点
|
||
/// </summary>
|
||
public static Transform FindChildRecursive(Transform parent, string childName)
|
||
{
|
||
// 首先检查直接子节点
|
||
Transform child = parent.Find(childName);
|
||
if (child != null)
|
||
return child;
|
||
|
||
// 如果直接子节点中没找到,递归查找每个子节点
|
||
for (int i = 0; i < parent.childCount; i++)
|
||
{
|
||
child = FindChildRecursive(parent.GetChild(i), childName);
|
||
if (child != null)
|
||
return child;
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 递归设置GameObject的静态标志
|
||
/// </summary>
|
||
public static void SetStaticFlagsRecursive(GameObject obj, StaticEditorFlags flags)
|
||
{
|
||
// 设置当前物体的静态标志
|
||
GameObjectUtility.SetStaticEditorFlags(obj, flags);
|
||
|
||
// 递归设置所有子物体
|
||
for (int i = 0; i < obj.transform.childCount; i++)
|
||
{
|
||
Transform child = obj.transform.GetChild(i);
|
||
SetStaticFlagsRecursive(child.gameObject, flags);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 给地面添加BoxCollider
|
||
/// </summary>
|
||
public static void AddBoxColliderToGround(GameObject ground)
|
||
{
|
||
if (ground != null)
|
||
{
|
||
Object.DestroyImmediate(ground.GetComponent<Collider>());
|
||
var boxCollider = ground.gameObject.AddComponent<BoxCollider>();
|
||
boxCollider.size = new Vector3(1, 1, 1);
|
||
boxCollider.center = new Vector3(0, 0, 0.5f);
|
||
|
||
EditorSceneManager.MarkSceneDirty(ground.gameObject.scene);
|
||
EditorSceneManager.SaveOpenScenes();
|
||
AssetDatabase.Refresh();
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError("地面节点不存在,无法添加BoxCollider");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置地面渲染队列
|
||
/// </summary>
|
||
public static void SetGroundRenderQueue(GameObject ground, int renderQueue)
|
||
{
|
||
if (ground != null)
|
||
{
|
||
GameObjectUtility.SetStaticEditorFlags(ground, StaticEditorFlags.ContributeGI);
|
||
var renderer = ground.GetComponent<Renderer>();
|
||
if (renderer != null)
|
||
{
|
||
renderer.shadowCastingMode = ShadowCastingMode.Off;
|
||
var materials = renderer.sharedMaterials;
|
||
foreach (var material in materials)
|
||
{
|
||
if (material != null)
|
||
{
|
||
renderer.shadowCastingMode = ShadowCastingMode.Off;
|
||
material.renderQueue = renderQueue;
|
||
Debug.Log($"将地面的材质 {material.name} 的RenderQueue改为{renderQueue}");
|
||
}
|
||
}
|
||
}
|
||
|
||
// 刷新资源以确保RenderQueue修改已保存
|
||
AssetDatabase.SaveAssets();
|
||
AssetDatabase.Refresh();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 解包预制体
|
||
/// </summary>
|
||
public static void UnpackPrefab(GameObject obj)
|
||
{
|
||
if (obj != null && PrefabUtility.IsPartOfPrefabInstance(obj))
|
||
{
|
||
Debug.Log($"解包场景{obj.scene.name} 的预制体: {obj.name}");
|
||
|
||
PrefabUtility.UnpackPrefabInstance(obj,
|
||
PrefabUnpackMode.Completely, InteractionMode.AutomatedAction);
|
||
|
||
EditorSceneManager.MarkSceneDirty(obj.scene);
|
||
EditorSceneManager.SaveOpenScenes();
|
||
|
||
// 强制刷新
|
||
AssetDatabase.Refresh();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 移除Scene中的重复EventSystem
|
||
/// </summary>
|
||
public static void RemoveRedundantEventSystems(Scene scene)
|
||
{
|
||
foreach (var rootObj in scene.GetRootGameObjects())
|
||
{
|
||
UnityEngine.EventSystems.EventSystem[] eventSystems = rootObj.GetComponentsInChildren<UnityEngine.EventSystems.EventSystem>();
|
||
if (null == eventSystems)
|
||
continue;
|
||
|
||
for (var i = 0; i < eventSystems.Length; ++i)
|
||
{
|
||
Object.DestroyImmediate(eventSystems[i].gameObject);
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置雾的位置
|
||
/// </summary>
|
||
public static void SetFogPosition(GameObject fog)
|
||
{
|
||
if (fog == null)
|
||
return;
|
||
var transform = fog.transform;
|
||
var position = transform.position;
|
||
transform.position = new Vector3(position.x, position.y + 0.01f, position.z);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取标准化的资源路径
|
||
/// </summary>
|
||
public static string GetAssetPath(string path)
|
||
{
|
||
// 已经是Assets路径格式
|
||
if (path.StartsWith("Assets"))
|
||
return path;
|
||
|
||
// 绝对路径转相对Assets路径
|
||
string fullPath = Path.GetFullPath(path);
|
||
string assetsFullPath = Path.GetFullPath(Application.dataPath);
|
||
|
||
if (fullPath.StartsWith(assetsFullPath))
|
||
return "Assets" + fullPath.Substring(assetsFullPath.Length).Replace('\\', '/');
|
||
|
||
return path;
|
||
}
|
||
} |