unity地形保存地形数据

using UnityEngine;
using UnityEditor;
using System.IO;

public class TerrainDataSaver : MonoBehaviour
{
    [Header("源 Terrain")]
    public Terrain sourceTerrain;

    [Header("保存路径(相对于 Assets)")]
    public string savePath = "SavedTerrains/MyTerrainData.asset";

    [ContextMenu("保存 TerrainData(含混合纹理)")]
    public void SaveTerrainData()
    {
        if (sourceTerrain == null)
        {
            Debug.LogError("❌ 请指定源地形!");
            return;
        }

        TerrainData sourceData = sourceTerrain.terrainData;
        TerrainData newData = new TerrainData();

        // ✅ 设置分辨率和大小
        newData.heightmapResolution = sourceData.heightmapResolution;
        newData.size = sourceData.size;
        newData.baseMapResolution = sourceData.baseMapResolution;
        newData.alphamapResolution = sourceData.alphamapResolution;
        newData.SetDetailResolution(sourceData.detailResolution, 16);

        // ✅ 设置 TerrainLayers(必须先设置)
        newData.terrainLayers = sourceData.terrainLayers;

        // ✅ 设置混合纹理(alphamap / splatmap)
        float[,,] alphaMaps = sourceData.GetAlphamaps(0, 0, sourceData.alphamapWidth, sourceData.alphamapHeight);
        newData.SetAlphamaps(0, 0, alphaMaps);

        // ✅ 设置树
        newData.treePrototypes = sourceData.treePrototypes;
        newData.treeInstances = sourceData.treeInstances;

        // ✅ 设置草(细节)
        newData.detailPrototypes = sourceData.detailPrototypes;
        for (int i = 0; i < sourceData.detailPrototypes.Length; i++)
        {
            int[,] detailLayer = sourceData.GetDetailLayer(0, 0, sourceData.detailWidth, sourceData.detailHeight, i);
            newData.SetDetailLayer(0, 0, i, detailLayer);
        }

        // ✅ 设置高度图(必须最后设置)
        float[,] heights = sourceData.GetHeights(0, 0, sourceData.heightmapResolution, sourceData.heightmapResolution);
        newData.SetHeights(0, 0, heights);

        // ✅ 保存 .asset 文件
        string fullPath = "Assets/" + savePath;
        string folderPath = Path.GetDirectoryName(fullPath);
        if (!AssetDatabase.IsValidFolder(folderPath))
        {
            Directory.CreateDirectory(folderPath);
            AssetDatabase.Refresh();
        }

        AssetDatabase.CreateAsset(newData, fullPath);
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();

        Debug.Log($"✅ TerrainData 保存成功(含纹理混合):{fullPath}");
    }

    [ContextMenu("导出第一层混合纹理为 PNG")]
    public void ExportSplatmapLayer0ToPNG()
    {
        if (sourceTerrain == null)
        {
            Debug.LogError("❌ 请指定源地形!");
            return;
        }

        TerrainData td = sourceTerrain.terrainData;
        int width = td.alphamapWidth;
        int height = td.alphamapHeight;

        float[,,] alphamaps = td.GetAlphamaps(0, 0, width, height);
        Texture2D tex = new Texture2D(width, height);

        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                float value = alphamaps[y, x, 0]; // 第一图层
                tex.SetPixel(x, y, new Color(value, value, value, 1));
            }
        }

        tex.Apply();

        string exportPath = Application.dataPath + "/SplatLayer0.png";
        File.WriteAllBytes(exportPath, tex.EncodeToPNG());
        AssetDatabase.Refresh();

        Debug.Log("✅ Splatmap Layer 0 导出成功:" + exportPath);
    }
}

使用方式:
创建一个空 GameObject,挂上此脚本;

拖入你的地形 sourceTerrain;

设置保存路径(例如:SavedTerrains/Level01.asset);

在 Inspector 三点菜单点击 → 保存完整 TerrainData(含纹理混合)。
✅ 生成结果包括:
类型 文件扩展名 储存内容
.asset MyTerrainData.asset 包含高度图、混合图、草、树
.terrainlayer Layer_0.terrainlayer 等 储存每个纹理层贴图及参数

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容