Terrain地形剪裁

实现:保留的原 1000×1000 正中间的 500×500,并且这个中间区域的中心点和世界坐标保持不变。

一、先确认坐标关系

假设原始 Terrain 是:

  • 大小:1000 × 1000
  • 中心位置:(0, 0, 0)
  • 世界范围:
    • X:-500 到 +500
    • Z:-500 到 +500

那么正中间 500×500 区域是:

  • X:-250 到 +250
  • Z:-250 到 +250
  • 中心点仍然是:(0, 0, 0)

如果你原来的 Terrain 坐标不是从 -500 开始,而是从 0 开始:

  • 原始范围:X 0~1000,Z 0~1000
  • 中心点:(500, 0, 500)
  • 中间 500×500 区域:
    • X:250 ~ 750
    • Z:250 ~ 750
    • 中心点:(500, 0, 500) 保持不变

所以你要裁的是:

以原地形中心点为中心,向内收缩 250 米后的正方形区域。

这个脚本会新建一个独立的 500×500 Terrain,保留原中心点位置,并生成独立 TerrainData。

cs 复制代码
using UnityEditor;
using UnityEngine;

public static class TerrainCenterCrop
{
    [MenuItem("Terrain/Extract Center 500x500")]
    public static void ExtractCenter500()
    {
        GameObject selected = Selection.activeGameObject;
        if (selected == null)
        {
            Debug.LogWarning("请先选中一个 Terrain GameObject");
            return;
        }

        Terrain sourceTerrain = selected.GetComponent<Terrain>();
        if (sourceTerrain == null)
        {
            Debug.LogWarning("选中对象不是 Terrain");
            return;
        }

        TerrainData sourceData = sourceTerrain.terrainData;

        int sourceResolution = sourceData.heightmapResolution;
        int destResolution = sourceResolution / 2;

        // 创建新的独立 TerrainData
        TerrainData newTerrainData = new TerrainData();
        newTerrainData.heightmapResolution = destResolution;
        newTerrainData.size = new Vector3(500f, sourceData.size.y, 500f);

        // 高度贴图分辨率也要减半
        int alphaWidth = Mathf.Max(1, sourceData.alphamapWidth / 2);
        int alphaHeight = Mathf.Max(1, sourceData.alphamapHeight / 2);

        // 提取中心 25% ~ 75% 的高度数据
        int startX = Mathf.FloorToInt(sourceResolution * 0.25f);
        int startZ = Mathf.FloorToInt(sourceResolution * 0.25f);

        float[,] centerHeights = sourceData.GetHeights(startX, startZ, destResolution, destResolution);
        newTerrainData.SetHeights(0, 0, centerHeights);

        // 复制地形层
        newTerrainData.splatPrototypes = sourceData.splatPrototypes;

        // 提取中心区域的贴图
        int alphaStartX = Mathf.FloorToInt(sourceData.alphamapWidth * 0.25f);
        int alphaStartZ = Mathf.FloorToInt(sourceData.alphamapHeight * 0.25f);

        float[,,] centerAlphas = sourceData.GetAlphamaps(alphaStartX, alphaStartZ, alphaWidth, alphaHeight);
        newTerrainData.SetAlphamaps(0, 0, centerAlphas);

        // 保存新 TerrainData
        AssetDatabase.CreateAsset(newTerrainData, "Assets/TerrainData_Center500x500.asset");
        AssetDatabase.SaveAssets();

        // 创建新 Terrain GameObject
        GameObject newTerrainObject = Terrain.CreateTerrainGameObject(newTerrainData);
        newTerrainObject.name = "Terrain_Center500x500";

        // 关键:保持原中心点不变
        newTerrainObject.transform.position = sourceTerrain.transform.position + new Vector3(250f, 0f, 250f);

        // 自动选中新地形
        Selection.activeGameObject = newTerrainObject;

        Debug.Log("已提取原地形中心 500x500,中心点位置保持不变");
    }
}

脚本使用方法

  1. 在 Unity 中创建脚本文件夹 Editor
  2. 新建脚本 TerrainCenterCrop.cs
  3. 把上面代码粘贴进去
  4. 选中原始 1000×1000 Terrain
  5. 点击菜单:
    Terrain > Extract Center 500x500

执行后会生成一个新的:

  • Terrain_Center500x500
  • TerrainData_Center500x500.asset

这个新地形是独立的,修改不会影响原地形。


为什么这个脚本中心点不会变?

因为它不是简单裁掉四周,而是按原地形坐标重新定位:

复制代码
newTerrainObject.transform.position = sourceTerrain.transform.position + new Vector3(250f, 0f, 250f);

假设原始 Terrain 是 1000×1000,从 0 开始:

  • 原始中心:(500, 0, 500)
  • 新 500×500 地形中心也会保持在:(500, 0, 500)
相关推荐
郝学胜-神的一滴15 小时前
AI 编程智能体 22:解析器赋能与实战落地全指南
人工智能·程序人生·游戏·unity·游戏引擎
BuHuaX18 小时前
Lua 与 ToLua:运行机制及热更新原理
开发语言·unity·junit·c#·lua
peter67682 天前
unity2d游戏开发经验总结
unity
郝学胜-神的一滴2 天前
游戏设计:原型与开发 19:U3D工位布置与性格说明书
人工智能·算法·unity·unreal engine·游戏策划·游戏设计
Aman19842 天前
Claude Code做Unity项目移植(二): 自动执行只读操作,告别频繁的
unity·游戏开发·vibe coding·claude code
暴走约伯3 天前
【VFX工具链源码拆解 02】告别机械劳动(上):一键统改百个子粒子颜色与批量重命名
3d·unity·c#·材质
郝学胜-神的一滴3 天前
游戏设计:原型与开发 18:Unity入门的第一课
人工智能·程序人生·游戏·ui·unity·游戏引擎
淡海水3 天前
09-01-内存-Unity资源生命周期全景
unity·c#·游戏引擎·.netcore·gc
LF男男3 天前
Flower Defense—UIFacade
unity
呆呆敲代码的小Y3 天前
【实战精选面试题】Unity精选面试题详细解答,按模块整理汇总
人工智能·游戏·unity·游戏引擎