BITFALL/Assets/Plugins/FImpossible Creations/Plugins - Level Design/PGG/Components/Tools/PGGTool_FlattenTerrain.cs

140 lines
4.6 KiB
C#

#if UNITY_EDITOR
using FIMSpace.FEditor;
#endif
using FIMSpace.Generating.Rules.PostEvents;
using System;
using UnityEngine;
namespace FIMSpace.Generating
{
[AddComponentMenu("FImpossible Creations/PGG/Tools/PGG Flatten Terrain")]
public class PGGTool_FlattenTerrain : MonoBehaviour, IGenerating
{
public bool FlattenOnGameStart = true;
[HideInInspector] public bool AllowPostGenerator = true;
//[Header("Detecting Terrain Object")]
//public LayerMask GroundRaycastMask = 1 << 0;
//[Tooltip("Most cases it will be 0,-1,0 so straight down")]
//public Vector3 RaycastDirection = Vector3.down;
//[Tooltip("How far collision raycast can go")]
//public float RaycastLength = 7f;
//[Tooltip("Casting ray from upper or lower position of the object")]
//public Vector3 OffsetRaycastOrigin = Vector3.up;
[Header("Terrain Shaping Parameters")]
[Range(0f, 1f)]
[Header("How much terrain should be flattened like opacity")]
public float FlattenAmount = 1f;
[Header("How far flatten-falloff should go")]
public float BrushRadius = 3f;
[Header("If ground should be leveled with object's origin or with some offset")]
public Vector3 OffsetGround = Vector3.zero;
[Header("Spherical falloff for flattening terrain level")]
[FPD_FixedCurveWindow(0f,0f,1f,1f)]
public AnimationCurve Falloff = AnimationCurve.EaseInOut(0f, 1f, 1f, 0f);
private void Start()
{
if (FlattenOnGameStart)
{
FlattenTerrain();
}
}
[NonSerialized] public Terrain backupTerrain = null;
[NonSerialized] public float[,] backupHeights = null;
public static Terrain GetTerrainIn(Vector3 wPos)
{
if (Terrain.activeTerrain == null) return null;
if (Terrain.activeTerrains == null) return null;
for (int t = 0; t < Terrain.activeTerrains.Length; t++)
{
var terr = Terrain.activeTerrains[t];
if (terr)
{
Vector3 locPos = terr.transform.InverseTransformPoint(wPos);
if (locPos.x < 0) continue;
if (locPos.x > terr.terrainData.bounds.max.x) continue;
if (locPos.z < 0) continue;
if (locPos.z > terr.terrainData.bounds.max.z) continue;
return terr;
}
}
return null;
}
public void FlattenTerrain()
{
backupTerrain = GetTerrainIn(transform.position);
backupHeights = SR_FlattenTerrain.DetectTerrainAndFlattenGroundLevel(gameObject, backupTerrain, FlattenAmount, BrushRadius, OffsetGround, Falloff);
}
#if UNITY_EDITOR
private void OnDrawGizmosSelected()
{
SR_FlattenTerrain.DrawTerrainFlatteningGizmos(gameObject, FlattenAmount, BrushRadius, OffsetGround, Falloff);
}
#endif
public void Generate()
{
if (!AllowPostGenerator) return;
FlattenTerrain();
}
public void PreviewGenerate()
{
if (!AllowPostGenerator) return;
FlattenTerrain();
}
public void IG_CallAfterGenerated() { }
}
#region Drawing 'Test Align' button inside inspector window
#if UNITY_EDITOR
[UnityEditor.CanEditMultipleObjects]
[UnityEditor.CustomEditor(typeof(PGGTool_FlattenTerrain))]
public class PGGTool_FlattenTerrainEditor : UnityEditor.Editor
{
public PGGTool_FlattenTerrain Get { get { if (_get == null) _get = (PGGTool_FlattenTerrain)target; return _get; } }
private PGGTool_FlattenTerrain _get;
//bool displayEvent = false;
public override void OnInspectorGUI()
{
UnityEditor.EditorGUILayout.HelpBox("This component is just simple utility tool for aligning unity terrain level below the object", UnityEditor.MessageType.Info);
FGUI_Inspector.LastGameObjectSelected = Get.gameObject;
DrawDefaultInspector();
GUILayout.Space(4);
if (GUILayout.Button("Test Flatten")) Get.FlattenTerrain();
if ( Get.backupHeights != null && Get.backupHeights.Length > 10 && Get.backupTerrain != null)
{
if (GUILayout.Button("Undo Flatten"))
{
Get.backupTerrain.terrainData.SetHeights(0, 0, Get.backupHeights);
Get.backupTerrain = null;
}
}
}
}
#endif
#endregion
}