using UnityEngine; using UnityEditor; using UnityEngine.SceneManagement; using UnityEditor.SceneManagement; #if UNITY_EDITOR public class BatchOcclusionCulling : EditorWindow { // 在类的成员变量中添加 private string targetCameraName = "Main Camera"; // 可以根据需要修改目标相机的名称 // private float cameraHeight = 1.7f; // private float gridSize = 1.0f; // private Vector2 gridDimensions = new Vector2(10, 10); // private Vector3 startPosition = Vector3.zero; // 烘焙参数 private float smallestOccluder = 5.0f; private float smallestHole = 0.25f; private float backfaceThreshold = 100.0f; [MenuItem("Tools/Batch Occlusion Culling")] static void OpenWindow() { GetWindow("批量遮挡剔除"); } void OnGUI() { EditorGUILayout.LabelField("遮挡剔除批处理设置", EditorStyles.boldLabel); // 添加相机名称设置 targetCameraName = EditorGUILayout.TextField("目标相机名称", targetCameraName); EditorGUILayout.Space(); EditorGUILayout.LabelField("烘焙参数", EditorStyles.boldLabel); smallestOccluder = EditorGUILayout.FloatField("最小遮挡物尺寸", smallestOccluder); smallestHole = EditorGUILayout.FloatField("最小孔洞尺寸", smallestHole); backfaceThreshold = EditorGUILayout.FloatField("背面阈值", backfaceThreshold); if (GUILayout.Button("开始烘焙")) { BakeOcclusionCulling(); } } void BakeOcclusionCulling() { // 获取当前场景 // Scene currentScene = SceneManager.GetActiveScene(); Scene currentScene = UnityEngine.SceneManagement.SceneManager.GetActiveScene(); // 获取场景的烘焙设置 SerializedObject sceneAsset = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath(currentScene.path)[0]); SerializedProperty occlusionCullingSettings = sceneAsset.FindProperty("m_OcclusionCullingSettings"); if (occlusionCullingSettings != null) { // 设置烘焙参数 occlusionCullingSettings.FindPropertyRelative("smallestOccluder").floatValue = smallestOccluder; occlusionCullingSettings.FindPropertyRelative("smallestHole").floatValue = smallestHole; occlusionCullingSettings.FindPropertyRelative("backfaceThreshold").floatValue = backfaceThreshold; sceneAsset.ApplyModifiedProperties(); } try { EditorUtility.DisplayProgressBar("烘焙进度", "正在进行遮挡剔除烘焙...", 0.9f); // 使用当前相机位置添加视图方向 AddViewDirections(); // 标记场景为脏 EditorSceneManager.MarkSceneDirty(currentScene); // 保存场景 EditorSceneManager.SaveScene(currentScene); // 打开遮挡剔除窗口 EditorApplication.ExecuteMenuItem("Window/Rendering/Occlusion Culling"); Debug.Log("请在 Occlusion Culling 窗口中点击 Bake 完成最终烘焙!"); } catch (System.Exception e) { Debug.LogError($"烘焙过程中出错: {e.Message}"); } finally { EditorUtility.ClearProgressBar(); } } void AddViewDirections() { float[] rotations = { 0, 45, 90, 135, 180, 225, 270, 315 }; // 查找场景中的目标相机 Camera targetCamera = GameObject.Find(targetCameraName)?.GetComponent(); if (targetCamera != null) { foreach (float angle in rotations) { targetCamera.transform.rotation = Quaternion.Euler(0, angle, 0); SceneView.RepaintAll(); } } else { Debug.LogError($"未找到名为 {targetCameraName} 的相机!"); } } } #endif