Net.Like.Xue.Tokyo/Packages-Local/Net.BITKit.Bounds.Unity/FlattenTerrainLayerTool.cs

82 lines
2.8 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using UnityEngine;
using UnityEditor;
public class FlattenTerrainLayerToWorldHeight : EditorWindow
{
Terrain terrain;
string targetLayerName = "Road";
float targetWorldHeight = 10f; // 米
float layerThreshold = 0.5f;
[MenuItem("Tools/Terrain/Flatten Layer To World Height")]
public static void ShowWindow()
{
GetWindow<FlattenTerrainLayerToWorldHeight>("Flatten Layer Height");
}
void OnGUI()
{
terrain = (Terrain)EditorGUILayout.ObjectField("目标 Terrain", terrain, typeof(Terrain), true);
targetLayerName = EditorGUILayout.TextField("目标 Terrain Layer 名", targetLayerName);
targetWorldHeight = EditorGUILayout.FloatField("世界空间高度 (米)", targetWorldHeight);
layerThreshold = EditorGUILayout.Slider("图层混合阈值", layerThreshold, 0f, 1f);
if (GUILayout.Button("拉平图层区域至目标高度"))
{
if (terrain == null) terrain = Terrain.activeTerrain;
if (terrain != null) FlattenLayerArea();
else Debug.LogError("未找到 Terrain");
}
}
void FlattenLayerArea()
{
TerrainData data = terrain.terrainData;
int heightmapWidth = data.heightmapResolution;
int heightmapHeight = data.heightmapResolution;
float[,] heights = data.GetHeights(0, 0, heightmapWidth, heightmapHeight);
int alphaWidth = data.alphamapWidth;
int alphaHeight = data.alphamapHeight;
float[,,] alphaMaps = data.GetAlphamaps(0, 0, alphaWidth, alphaHeight);
int layerIndex = -1;
for (int i = 0; i < data.terrainLayers.Length; i++)
{
if (data.terrainLayers[i].name == targetLayerName)
{
layerIndex = i;
break;
}
}
if (layerIndex == -1)
{
Debug.LogError("找不到指定的 Terrain Layer" + targetLayerName);
return;
}
float normalizedHeight = targetWorldHeight / data.size.y;
int changed = 0;
for (int y = 0; y < heightmapHeight; y++)
{
for (int x = 0; x < heightmapWidth; x++)
{
int alphaX = Mathf.Clamp(Mathf.RoundToInt((float)x / heightmapWidth * alphaWidth), 0, alphaWidth - 1);
int alphaY = Mathf.Clamp(Mathf.RoundToInt((float)y / heightmapHeight * alphaHeight), 0, alphaHeight - 1);
float weight = alphaMaps[alphaY, alphaX, layerIndex];
if (weight > layerThreshold)
{
heights[y, x] = normalizedHeight;
changed++;
}
}
}
data.SetHeights(0, 0, heights);
Debug.Log($"✅ 拉平完成!将 {changed} 个点高度设置为 {targetWorldHeight} 米");
}
}