331 lines
13 KiB
C#

using System;
using System.Linq;
using Unity.HLODSystem.SpaceManager;
using Unity.HLODSystem.Utils;
using UnityEditor;
using UnityEngine;
namespace Unity.HLODSystem
{
[CustomEditor(typeof(HLOD))]
public class HLODEditor : Editor
{
public static class Styles
{
public static GUIContent GenerateButtonEnable = new GUIContent("Generate", "Generate HLOD mesh.");
public static GUIContent GenerateButtonExists = new GUIContent("Generate", "HLOD already generated.");
public static GUIContent DestroyButtonEnable = new GUIContent("Destroy", "Destroy HLOD mesh.");
public static GUIContent DestroyButtonNotExists = new GUIContent("Destroy", "HLOD must be created before the destroying.");
public static GUIStyle RedTextColor = new GUIStyle();
public static GUIStyle BlueTextColor = new GUIStyle();
static Styles()
{
RedTextColor.normal.textColor = Color.red;
BlueTextColor.normal.textColor = new Color(0.4f, 0.5f, 1.0f);
}
}
private SerializedProperty m_ChunkSizeProperty;
private SerializedProperty m_LODDistanceProperty;
private SerializedProperty m_CullDistanceProperty;
private SerializedProperty m_MinObjectSizeProperty;
private LODSlider m_LODSlider;
private Type[] m_SpaceSplitterTypes;
private string[] m_SpaceSplitterNames;
private Type[] m_BatcherTypes;
private string[] m_BatcherNames;
private Type[] m_SimplifierTypes;
private string[] m_SimplifierNames;
private Type[] m_StreamingTypes;
private string[] m_StreamingNames;
private Type[] m_UserDataSerializerTypes;
private string[] m_UserDataSerializerNames;
private bool isShowCommon = true;
private bool isShowSpaceSplitter = true;
private bool isShowBatcher = true;
private bool isShowSimplifier = true;
private bool isShowStreaming = true;
private bool isShowUserDataSerializer = true;
private bool isFirstOnGUI = true;
private ISpaceSplitter m_splitter;
[InitializeOnLoadMethod]
static void InitTagTagUtils()
{
if (LayerMask.NameToLayer(HLOD.HLODLayerStr) == -1)
{
TagUtils.AddLayer(HLOD.HLODLayerStr);
Tools.lockedLayers |= 1 << LayerMask.NameToLayer(HLOD.HLODLayerStr);
}
}
void OnEnable()
{
m_ChunkSizeProperty = serializedObject.FindProperty("m_ChunkSize");
m_LODDistanceProperty = serializedObject.FindProperty("m_LODDistance");
m_CullDistanceProperty = serializedObject.FindProperty("m_CullDistance");
m_MinObjectSizeProperty = serializedObject.FindProperty("m_MinObjectSize");
m_LODSlider = new LODSlider(true, "Cull");
m_LODSlider.InsertRange("High", m_LODDistanceProperty);
m_LODSlider.InsertRange("Low", m_CullDistanceProperty);
m_SpaceSplitterTypes = SpaceManager.SpaceSplitterTypes.GetTypes();
m_SpaceSplitterNames = m_SpaceSplitterTypes.Select(t => t.Name).ToArray();
m_BatcherTypes = BatcherTypes.GetTypes();
m_BatcherNames = m_BatcherTypes.Select(t => t.Name).ToArray();
m_SimplifierTypes = Simplifier.SimplifierTypes.GetTypes();
m_SimplifierNames = m_SimplifierTypes.Select(t => t.Name).ToArray();
m_StreamingTypes = Streaming.StreamingBuilderTypes.GetTypes();
m_StreamingNames = m_StreamingTypes.Select(t => t.Name).ToArray();
m_UserDataSerializerTypes = Serializer.UserDataSerializerTypes.GetTypes();
m_UserDataSerializerNames = m_UserDataSerializerTypes.Select(t => t.Name).ToArray();
isFirstOnGUI = true;
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUI.BeginChangeCheck();
HLOD hlod = target as HLOD;
if (hlod == null)
{
EditorGUILayout.LabelField("HLOD is null.");
return;
}
if (m_splitter == null)
{
m_splitter = SpaceSplitterTypes.CreateInstance(hlod);
}
isShowCommon = EditorGUILayout.BeginFoldoutHeaderGroup(isShowCommon, "Common");
if (isShowCommon == true)
{
EditorGUILayout.PropertyField(m_ChunkSizeProperty);
m_ChunkSizeProperty.floatValue = HLODUtils.GetChunkSizePropertyValue(m_ChunkSizeProperty.floatValue);
if (m_splitter != null)
{
var bounds = hlod.GetBounds();
int depth = m_splitter.CalculateTreeDepth(bounds, m_ChunkSizeProperty.floatValue);
EditorGUILayout.LabelField($"The HLOD tree will be created with {depth} levels.", Styles.BlueTextColor);
if (depth > 5)
{
EditorGUILayout.LabelField($"Node Level Count greater than 5 may cause a frozen Editor.",
Styles.RedTextColor);
EditorGUILayout.LabelField($"I recommend keeping the level under 5.", Styles.RedTextColor);
}
}
m_LODSlider.Draw();
EditorGUILayout.PropertyField(m_MinObjectSizeProperty);
}
EditorGUILayout.EndFoldoutHeaderGroup();
isShowSpaceSplitter = EditorGUILayout.BeginFoldoutHeaderGroup(isShowSpaceSplitter, "SpaceSplitter");
if (isShowSpaceSplitter)
{
EditorGUI.indentLevel += 1;
if (m_SpaceSplitterTypes.Length > 0)
{
EditorGUI.BeginChangeCheck();
int spaceSplitterIndex = Math.Max(Array.IndexOf(m_SpaceSplitterTypes, hlod.SpaceSplitterType), 0);
spaceSplitterIndex = EditorGUILayout.Popup("SpaceSplitter", spaceSplitterIndex, m_SpaceSplitterNames);
hlod.SpaceSplitterType = m_SpaceSplitterTypes[spaceSplitterIndex];
var info = m_SpaceSplitterTypes[spaceSplitterIndex].GetMethod("OnGUI");
if (info != null)
{
if ( info.IsStatic == true )
{
info.Invoke(null, new object[] { hlod.SpaceSplitterOptions });
}
}
if (EditorGUI.EndChangeCheck())
{
m_splitter = SpaceSplitterTypes.CreateInstance(hlod);
}
if (m_splitter != null)
{
int subTreeCount = m_splitter.CalculateSubTreeCount(hlod.GetBounds());
EditorGUILayout.LabelField($"The HLOD tree will be created with {subTreeCount} sub trees.",
Styles.BlueTextColor);
}
}
else
{
EditorGUILayout.LabelField("Cannot find SpaceSplitters.");
}
EditorGUI.indentLevel -= 1;
}
EditorGUILayout.EndFoldoutHeaderGroup();
isShowSimplifier = EditorGUILayout.BeginFoldoutHeaderGroup(isShowSimplifier, "Simplifier");
if (isShowSimplifier == true)
{
EditorGUI.indentLevel += 1;
if (m_SimplifierTypes.Length > 0)
{
int simplifierIndex = Math.Max(Array.IndexOf(m_SimplifierTypes, hlod.SimplifierType), 0);
simplifierIndex = EditorGUILayout.Popup("Simplifier", simplifierIndex, m_SimplifierNames);
hlod.SimplifierType = m_SimplifierTypes[simplifierIndex];
var info = m_SimplifierTypes[simplifierIndex].GetMethod("OnGUI");
if (info != null)
{
if (info.IsStatic == true)
{
info.Invoke(null, new object[] {hlod.SimplifierOptions});
}
}
}
else
{
EditorGUILayout.LabelField("Cannot find Simplifiers.");
}
EditorGUI.indentLevel -= 1;
}
EditorGUILayout.EndFoldoutHeaderGroup();
isShowBatcher = EditorGUILayout.BeginFoldoutHeaderGroup(isShowBatcher, "Batcher");
if (isShowBatcher == true)
{
EditorGUI.indentLevel += 1;
if (m_BatcherTypes.Length > 0)
{
int batcherIndex = Math.Max(Array.IndexOf(m_BatcherTypes, hlod.BatcherType), 0);
batcherIndex = EditorGUILayout.Popup("Batcher", batcherIndex, m_BatcherNames);
hlod.BatcherType = m_BatcherTypes[batcherIndex];
var info = m_BatcherTypes[batcherIndex].GetMethod("OnGUI");
if (info != null)
{
if (info.IsStatic == true)
{
info.Invoke(null, new object[] {hlod, isFirstOnGUI });
}
}
}
else
{
EditorGUILayout.LabelField("Cannot find Batchers.");
}
EditorGUI.indentLevel -= 1;
}
EditorGUILayout.EndFoldoutHeaderGroup();
isShowStreaming = EditorGUILayout.BeginFoldoutHeaderGroup(isShowStreaming, "Streaming");
if (isShowStreaming == true)
{
EditorGUI.indentLevel += 1;
if (m_StreamingTypes.Length > 0)
{
int streamingIndex = Math.Max(Array.IndexOf(m_StreamingTypes, hlod.StreamingType), 0);
streamingIndex = EditorGUILayout.Popup("Streaming", streamingIndex, m_StreamingNames);
hlod.StreamingType = m_StreamingTypes[streamingIndex];
var info = m_StreamingTypes[streamingIndex].GetMethod("OnGUI");
if (info != null)
{
if (info.IsStatic == true)
{
info.Invoke(null, new object[] { hlod.StreamingOptions });
}
}
}
else
{
EditorGUILayout.LabelField("Cannot find StreamingSetters.");
}
EditorGUI.indentLevel -= 1;
}
EditorGUILayout.EndFoldoutHeaderGroup();
isShowUserDataSerializer =
EditorGUILayout.BeginFoldoutHeaderGroup(isShowUserDataSerializer, "UserData serializer");
if (isShowUserDataSerializer)
{
EditorGUI.indentLevel += 1;
if (m_UserDataSerializerTypes.Length > 0)
{
int serializerIndex =
Math.Max(Array.IndexOf(m_UserDataSerializerTypes, hlod.UserDataSerializerType), 0);
serializerIndex =
EditorGUILayout.Popup("UserDataSerializer", serializerIndex, m_UserDataSerializerNames);
hlod.UserDataSerializerType = m_UserDataSerializerTypes[serializerIndex];
}
else
{
EditorGUILayout.LabelField("Cannot find UserDataSerializer.");
}
EditorGUI.indentLevel -= 1;
}
EditorGUILayout.EndFoldoutHeaderGroup();
GUIContent generateButton = Styles.GenerateButtonEnable;
GUIContent destroyButton = Styles.DestroyButtonNotExists;
if (hlod.GeneratedObjects.Count > 0 )
{
generateButton = Styles.GenerateButtonExists;
destroyButton = Styles.DestroyButtonEnable;
}
EditorGUILayout.Space();
GUI.enabled = generateButton == Styles.GenerateButtonEnable;
if (GUILayout.Button(generateButton))
{
CoroutineRunner.RunCoroutine(HLODCreator.Create(hlod));
}
GUI.enabled = destroyButton == Styles.DestroyButtonEnable;
if (GUILayout.Button(destroyButton))
{
CoroutineRunner.RunCoroutine(HLODCreator.Destroy(hlod));
}
if (EditorGUI.EndChangeCheck())
{
EditorUtility.SetDirty(hlod);
}
GUI.enabled = true;
serializedObject.ApplyModifiedProperties();
isFirstOnGUI = false;
}
}
}