Unity地形关联出错的解决办法以及地形深度拷贝

文章讲述了在Unity中遇到的地形数据关联错误,提供了解决方案和一个用于快速复制地形数据的脚本,有助于避免此类问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题

最近发现unity地形系统的一个bug,导入的场景地形数据关联错乱了,关联到别的场景的地形数据了,meta替换了也没用,不清楚它具体是怎么关联的。

看下面的案例:

可以看到正常这个场景的地形数据应该关联的是Scene_Empty_Terrain的数据,但是现在它关联到别的了。

那我们强制把正确的地形数据拖过去行不行,我们试下!

我们发现,强制拖过去会有一个警告,意思大概是地形数据和该地形的collider数据不匹配。而在Terrain的Inspector界面并没有找到任何的关联Terrain Data的地方。

 解决办法

解决方法有两个: 

切换到Debug模式,可以暴露出来Terrain Data参数,替换即可。

方法1
  • 右键这里的小箭头,切换成Debug模式
  • 我们能看到Terrain Data参数暴露出来了,将正确的Terrain Data拖过去替换即可
方法2

其实使用上面的方式已经可以解决了,第二种是想推荐下下面的地形拷贝类,本鱼蛋自己也做个备份,方便后续使用。这个地形深度拷贝也很有用,在一些场景比如想复制一份出来删除东西作为导航网格,可以这样操作。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class TerrainDataTransfer : EditorWindow {

    TerrainData terrainDataFrom;
    TerrainData terrainDataTo;
    bool isJustCopy;

    [MenuItem("Custom/TerrainDataTransfer")]
    private static void ShowWindow() {
        var window = GetWindow<TerrainDataTransfer>();
        window.titleContent = new GUIContent("TerrainDataTransfer");
        window.Show();
    }

    private void OnGUI() {
        GUILayout.Label("原始地形数据");
        terrainDataFrom = (TerrainData)EditorGUILayout.ObjectField(terrainDataFrom,typeof(TerrainData),true);
        
        GUILayout.Label("目标地形数据");
        terrainDataTo = (TerrainData)EditorGUILayout.ObjectField(terrainDataTo,typeof(TerrainData),true);
        
        isJustCopy = GUILayout.Toggle(isJustCopy,"仅复制");

        if(GUILayout.Button("复制terrain")){
            TransferData(terrainDataFrom,terrainDataTo);
        }
    }

    private void TransferData(TerrainData dataFrom, TerrainData dataTo){
        //dataTo = new TerrainData();  会导致重定向,从而找不到本尊
        ///复制参数
        dataTo.heightmapResolution = dataFrom.heightmapResolution;
        dataTo.size = dataFrom.size;
        dataTo.wavingGrassAmount = dataFrom.wavingGrassAmount;
        dataTo.wavingGrassSpeed = dataFrom.wavingGrassSpeed;
        dataTo.wavingGrassStrength = dataFrom.wavingGrassStrength;
        dataTo.wavingGrassTint = dataFrom.wavingGrassTint;
        dataTo.detailPrototypes = dataFrom.detailPrototypes;
        dataTo.treeInstances = dataFrom.treeInstances;
        dataTo.treePrototypes = dataFrom.treePrototypes;
        dataTo.alphamapResolution = dataFrom.alphamapResolution;
        dataTo.baseMapResolution = dataFrom.baseMapResolution;
        dataTo.splatPrototypes = dataFrom.splatPrototypes;

        float[,] heights = dataFrom.GetHeights(0,0, dataFrom.heightmapResolution,dataFrom.heightmapResolution);
        dataTo.SetHeights(0,0,heights);

        float[,,] alphaMap = dataFrom.GetAlphamaps(0,0, dataFrom.alphamapWidth, dataFrom.alphamapHeight);
        dataTo.SetAlphamaps(0,0, alphaMap);

        ///是否只是拷贝数据
        if(isJustCopy)
            return;

        //在场景中创建地表
        GameObject obj = Terrain.CreateTerrainGameObject(dataTo);
        obj.name = "TerrainNew";
    }
}
  •  将上面的脚本导入到项目中

  • 打开编辑器窗口Custom/TerrainDataTransfer

  • 选择原始地形和目标地形文件,点击复制terrain按钮,即可自动在场景中创建出地形出来

  • 如果勾选“仅复制”选项,那么只会把原始地形和目标地形数据同步一份过去

 希望能帮到大家,喜欢本文章也点个赞加个关注,谢谢,我会长期分享自己的踩坑经验。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鱼蛋-Felix

如果对你有用,可以请我喝杯可乐

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值