82 lines
2.8 KiB
C#
82 lines
2.8 KiB
C#
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} 米");
|
||
}
|
||
}
|