Files
2025-06-09 23:23:13 +08:00

231 lines
11 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEngine.Rendering;
namespace JBooth.MicroVerseCore
{
internal class DetailWizardSharedStyles
{
public readonly GUIStyle helpBoxBig;
public readonly GUIContent noiseSeed = EditorGUIUtility.TrTextContent("Noise Seed", "Specifies the random seed value for detail object placement.");
public readonly GUIContent noiseSpread = EditorGUIUtility.TrTextContent("Noise Spread", "Controls the spatial frequency of the noise pattern used to vary the scale and color of the detail objects.");
public readonly GUIContent detailDensity = EditorGUIUtility.TrTextContent("Detail density", "Controls detail density for this detail prototype, relative to it's size. Only enabled in \"Coverage\" detail scatter mode.");
public readonly GUIContent holeEdgePadding = EditorGUIUtility.TrTextContent("Hole Edge Padding (%)", "Controls how far away detail objects are from the edge of the hole area.\n\nSpecify this value as a percentage of the detail width, which determines the radius of the circular area around the detail object used for hole testing.");
public readonly GUIContent useDensityScaling = EditorGUIUtility.TrTextContent("Affected by Density Scale", "Toggles whether or not this detail prototype should be affected by the global density scaling setting in the Terrain settings.");
public readonly GUIContent alignToGround = EditorGUIUtility.TrTextContent("Align To Ground (%)", "Rotate detail axis to ground normal direction.");
public readonly GUIContent positionJitter = EditorGUIUtility.TrTextContent("Position Jitter (%)", "Controls the randomness of the detail distribution, from ordered to random. Only available when legacy distribution in Quality Settings is turned off.");
public DetailWizardSharedStyles()
{
helpBoxBig = new GUIStyle("HelpBox")
{
fontSize = EditorStyles.label.fontSize
};
}
private static DetailWizardSharedStyles s_Styles = null;
public static DetailWizardSharedStyles Instance
{
get
{
if (s_Styles == null)
s_Styles = new DetailWizardSharedStyles();
return s_Styles;
}
}
};
public enum TerrainDetailMeshRenderMode
{
Mesh,
Texture,
BillboardTexture
}
public class TerrainDetailMeshWizard : ScriptableWizard
{
DetailPrototypeSerializable prototype;
public static TerrainDetailMeshRenderMode GetRenderMode(DetailPrototypeSerializable prototype)
{
switch (prototype.renderMode)
{
case DetailRenderMode.GrassBillboard:
return TerrainDetailMeshRenderMode.BillboardTexture;
case DetailRenderMode.Grass:
return TerrainDetailMeshRenderMode.Texture;
default:
return TerrainDetailMeshRenderMode.Mesh;
}
}
void DoApply()
{
if (MicroVerse.instance != null)
MicroVerse.instance.Invalidate(stamp.GetBounds(), MicroVerse.InvalidateType.Tree);
}
void OnWizardCreate()
{
DoApply();
}
void OnWizardOtherButton()
{
DoApply();
}
void OnWizardUpdate()
{
}
static DetailStamp stamp;
public static bool DrawInspector(DetailStamp ds, DetailPrototypeSerializable prototype)
{
stamp = ds;
return DrawInspector(prototype);
}
public static bool DrawInspector(DetailPrototypeSerializable prototype)
{
EditorGUI.BeginChangeCheck();
var renderMode = GetRenderMode(prototype);
if (UnityEngine.Rendering.GraphicsSettings.currentRenderPipeline == null
|| UnityEngine.Rendering.GraphicsSettings.currentRenderPipeline.terrainDetailGrassBillboardShader != null
|| UnityEngine.Rendering.GraphicsSettings.currentRenderPipeline.terrainDetailGrassShader != null)
{
var orm = renderMode;
renderMode = (TerrainDetailMeshRenderMode)EditorGUILayout.EnumPopup("Render Mode", renderMode);
if (orm != renderMode)
{
if (renderMode == TerrainDetailMeshRenderMode.Texture)
{
prototype.renderMode = DetailRenderMode.Grass;
}
else if (renderMode == TerrainDetailMeshRenderMode.BillboardTexture)
{
prototype.renderMode = DetailRenderMode.GrassBillboard;
}
else
{
prototype.renderMode = DetailRenderMode.VertexLit;
}
}
}
if (prototype.renderMode == DetailRenderMode.VertexLit)
{
prototype.prototype = EditorGUILayout.ObjectField("Detail Prefab", prototype.prototype, typeof(GameObject), false) as GameObject;
prototype.prototypeTexture = null;
prototype.usePrototypeMesh = true;
if (prototype.prototype != null)
{
var lod = prototype.prototype.GetComponent<LODGroup>();
if (lod != null)
{
EditorGUILayout.HelpBox("LOD Ground Found\nThis is not supported by Unity's terrain system, however some 3rd party renderer's allow it. The first LOD will be set to be used instead.", MessageType.Info);
}
}
}
else
{
prototype.usePrototypeMesh = false;
prototype.prototypeTexture = EditorGUILayout.ObjectField("Grass Texture", prototype.prototypeTexture, typeof(Texture2D), false) as Texture2D;
prototype.prototype = null;
}
if (prototype.usePrototypeMesh && prototype.prototype != null)
{
#if UNITY_2022_2_OR_NEWER
prototype.alignToGround = EditorGUILayout.Slider(DetailWizardSharedStyles.Instance.alignToGround, prototype.alignToGround * 100, 0, 100) / 100.0f;
GUI.enabled = !QualitySettings.useLegacyDetailDistribution;
prototype.positionJitter = EditorGUILayout.Slider(DetailWizardSharedStyles.Instance.positionJitter, prototype.positionJitter * 100, 0, 100) / 100.0f;
GUI.enabled = true;
#endif
prototype.minWidth = EditorGUILayout.FloatField("Min Width", prototype.minWidth);
prototype.maxWidth = EditorGUILayout.FloatField("Max Width", prototype.maxWidth);
prototype.minHeight = EditorGUILayout.FloatField("Min Height", prototype.minHeight);
prototype.maxHeight = EditorGUILayout.FloatField("Max Height", prototype.maxHeight);
prototype.noiseSeed = EditorGUILayout.IntField(DetailWizardSharedStyles.Instance.noiseSeed, prototype.noiseSeed);
prototype.noiseSpread = EditorGUILayout.FloatField(DetailWizardSharedStyles.Instance.noiseSpread, prototype.noiseSpread);
prototype.holeEdgePadding = EditorGUILayout.Slider(DetailWizardSharedStyles.Instance.holeEdgePadding, prototype.holeEdgePadding * 100, 0, 100) / 100.0f;
prototype.density = EditorGUILayout.Slider(DetailWizardSharedStyles.Instance.detailDensity, prototype.density, 0, 8);
if (!prototype.useInstancing)
{
prototype.healthyColor = EditorGUILayout.ColorField("Healthy Color", prototype.healthyColor);
prototype.dryColor = EditorGUILayout.ColorField("Dry Color", prototype.dryColor);
}
GUI.enabled = true;
prototype.useInstancing = EditorGUILayout.Toggle("Use GPU Instancing", prototype.useInstancing);
#if UNITY_2022_2_OR_NEWER
prototype.useDensityScaling = EditorGUILayout.Toggle(DetailWizardSharedStyles.Instance.useDensityScaling, prototype.useDensityScaling);
#endif
}
else if (prototype.usePrototypeMesh == false)
{
#if UNITY_2022_2_OR_NEWER
prototype.alignToGround = EditorGUILayout.Slider(DetailWizardSharedStyles.Instance.alignToGround, prototype.alignToGround * 100, 0, 100) / 100.0f;
prototype.positionJitter = EditorGUILayout.Slider(DetailWizardSharedStyles.Instance.positionJitter, prototype.positionJitter * 100, 0, 100) / 100.0f;
prototype.targetCoverage = EditorGUILayout.Slider(new GUIContent("Target Coverage"), prototype.targetCoverage * 100, 0, 100) / 100.0f;
#endif
prototype.minWidth = EditorGUILayout.FloatField("Min Width", prototype.minWidth);
prototype.maxWidth = EditorGUILayout.FloatField("Max Width", prototype.maxWidth);
prototype.minHeight = EditorGUILayout.FloatField("Min Height", prototype.minHeight);
prototype.maxHeight = EditorGUILayout.FloatField("Max Height", prototype.maxHeight);
prototype.noiseSeed = EditorGUILayout.IntField(DetailWizardSharedStyles.Instance.noiseSeed, prototype.noiseSeed);
prototype.noiseSpread = EditorGUILayout.FloatField(DetailWizardSharedStyles.Instance.noiseSpread, prototype.noiseSpread);
prototype.density = EditorGUILayout.Slider(DetailWizardSharedStyles.Instance.detailDensity, prototype.density, 0, 5);
prototype.holeEdgePadding = EditorGUILayout.Slider(DetailWizardSharedStyles.Instance.holeEdgePadding, prototype.holeEdgePadding * 100, 0, 100) / 100.0f;
prototype.healthyColor = EditorGUILayout.ColorField("Healthy Color", prototype.healthyColor);
prototype.dryColor = EditorGUILayout.ColorField("Dry Color", prototype.dryColor);
prototype.useDensityScaling = EditorGUILayout.Toggle(DetailWizardSharedStyles.Instance.useDensityScaling, prototype.useDensityScaling);
prototype.minHeight = Mathf.Max(0f, prototype.minHeight);
prototype.minWidth = Mathf.Max(0f, prototype.minWidth);
prototype.maxHeight = Mathf.Max(prototype.minHeight, prototype.maxHeight);
prototype.maxWidth = Mathf.Max(prototype.minWidth, prototype.maxWidth);
}
if (EditorGUI.EndChangeCheck())
{
if (MicroVerse.instance != null)
{
if (stamp != null)
{
MicroVerse.instance.Invalidate(stamp.GetBounds(), MicroVerse.InvalidateType.Tree);
}
else
{
MicroVerse.instance.Invalidate(null, MicroVerse.InvalidateType.Tree);
}
}
return true;
}
return false;
}
protected override bool DrawWizardGUI()
{
return DrawInspector(stamp, prototype);
}
}
}