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

82 lines
2.8 KiB
C#
Raw Normal View History

2025-06-24 23:49:13 +08:00
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} 米");
}
}