1. using System;
2. using System.Collections.Generic;
3. using System.IO;
4. using UnityEditor;
5. using UnityEngine;
7. public class BatchSetLodGroupWindow : EditorWindow{
9. bool includeSubdirectories = true;
10. LODFadeMode fadeMode = LODFadeMode.None;
12. float cullRatio = 0.01f;
14. public float[] lodWeights = [new](http://www.google.com/search?q=new+msdn.microsoft.com) float[] { 0.6f, 0.3f, 0.1f };
16. string path = string.Empty;
18. [MenuItem("Tools/BatchSetLodGroups")]
19. public static void ShowWindow() {
20. //Show existing window instance. If one doesn't exist, make one.
21. EditorWindow.GetWindow([typeof](http://www.google.com/search?q=typeof+msdn.microsoft.com)(BatchSetLodGroupWindow));
22. }
24. void OnGUI() {
26. GUILayout.Label("LODGroup Settings", EditorStyles.boldLabel);
28. EditorGUILayout.BeginHorizontal();
29. EditorGUILayout.PrefixLabel("Select Directory");
30. if (GUILayout.Button("Browse")) {
31. path = EditorUtility.OpenFolderPanel("Select Directory", "", "");
32. }
33. EditorGUILayout.EndHorizontal();
35. EditorGUILayout.BeginHorizontal();
36. EditorGUILayout.PrefixLabel("Current Path");
37. EditorGUILayout.LabelField(path);
38. EditorGUILayout.EndHorizontal();
40. includeSubdirectories = EditorGUILayout.Toggle("Include Subdirectories", includeSubdirectories);
42. EditorGUILayout.BeginHorizontal();
43. EditorGUILayout.PrefixLabel("Fade Mode");
44. fadeMode = (LODFadeMode)EditorGUILayout.EnumPopup((Enum)fadeMode);
45. EditorGUILayout.EndHorizontal();
47. EditorGUILayout.BeginHorizontal();
48. EditorGUILayout.PrefixLabel("Cull Ratio (0.01 = 1%)");
49. cullRatio = EditorGUILayout.FloatField(cullRatio);
50. EditorGUILayout.EndHorizontal();
52. EditorGUILayout.LabelField("LOD Level Weights (will be normalized to 1)");
54. ScriptableObject target = this;
55. SerializedObject so = [new](http://www.google.com/search?q=new+msdn.microsoft.com) SerializedObject(target);
56. SerializedProperty prop = so.FindProperty([nameof](http://www.google.com/search?q=nameof+msdn.microsoft.com)(lodWeights));
57. EditorGUILayout.PropertyField(prop, true); // True means show children
58. so.ApplyModifiedProperties(); // Remember to apply modified properties
60. if (GUILayout.Button("Apply")) {
61. if (!string.IsNullOrWhiteSpace(path)) {
63. PerformActionOnPrefab(path, this.includeSubdirectories, GetSetLoadGroup(fadeMode,cullRatio, this.lodWeights));
64. }
65. }
67. Func<GameObject, bool> GetSetLoadGroup(LODFadeMode fadeMode,float cullRatio, float[] lodWeights) {
68. return x => SetLodGroupInner(x, fadeMode,cullRatio, lodWeights);
69. }
71. bool SetLodGroupInner(GameObject prefab, LODFadeMode fadeMode,float cullRatio, float[] lodWeights) {
73. if (lodWeights == null || lodWeights.Length == 0) return false;
74. LODGroup[] lodGroups = prefab.GetComponentsInChildren<LODGroup>(true);
76. if (lodGroups == null || lodGroups.Length <= 0) {
77. return false;
78. }
80. for (int i = 0; i < lodGroups.Length; i++) {
81. LODGroup lodGroup = lodGroups[i];
83. lodGroup.fadeMode = fadeMode;
84. LOD[] lods = lodGroup.GetLODs();
86. float weightSum = 0;
87. for (int k = 0; k < lods.Length; k++) {
89. if (k >= lodWeights.Length) {
90. weightSum += lodWeights[lodWeights.Length - 1];
91. } else {
92. weightSum += lodWeights[k];
93. }
94. }
97. float maxLength = 1 - cullRatio;
98. float curLodPos = 1;
99. for (int j = 0; j < lods.Length; j++) {
101. float weight = j < lodWeights.Length ? lodWeights[j] : lodWeights[lodWeights.Length - 1];
103. float lengthRatio = weightSum != 0 ? weight / weightSum : 1;
105. float lodLength = maxLength * lengthRatio;
106. curLodPos = curLodPos - lodLength;
108. lods[j].screenRelativeTransitionHeight = curLodPos;
109. }
112. lodGroup.SetLODs(lods);
113. }
115. return true;
116. }
117. }
120. //action: input prefab output should save to prefab
121. void PerformActionOnPrefab(string path, bool includeSubdirectories,Func<GameObject,bool> action) {
122. string[] files = Directory.GetFiles(path,"*.prefab", includeSubdirectories ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
124. foreach (var file in files) {
125. GameObject prefabGO = PrefabUtility.LoadPrefabContents(file);
127. if (prefabGO != null) {
128. action(prefabGO);
130. PrefabUtility.SaveAsPrefabAsset(prefabGO, file);
131. PrefabUtility.UnloadPrefabContents(prefabGO);
132. }
133. }
135. }
137. }
网友评论