You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在无Terrain的场景中依据高度随机生成路点对象?

问题背景

原有Unity脚本依赖Terrain组件实现随机路点生成,但当前场景采用资源包中的山地模型(无Terrain组件),需要修改脚本适配新场景。

原有脚本

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

public class SpawnObjects : MonoBehaviour
{
    public GameObject prefab;
    public Terrain terrain;
    public int numberOfObjects;
    public float duration;
    public float yOffset = 0.5f;

    private float terrainWidth;
    private float terrainLength;

    private float xTerrainPos;
    private float zTerrainPos;


    void Awake()
    {
        //Get terrain size
        terrainWidth = terrain.terrainData.size.x;
        terrainLength = terrain.terrainData.size.z;

        //Get terrain position
        xTerrainPos = terrain.transform.position.x;
        zTerrainPos = terrain.transform.position.z;

        StartCoroutine(Generate());
    }

    IEnumerator Generate()
    {
        //Generate the Prefab on the generated position
        for (int i = 0; i < numberOfObjects; i++)
        {
            //Generate random x,z,y position on the terrain
            float randX = UnityEngine.Random.Range(xTerrainPos, xTerrainPos + terrainWidth);
            float randZ = UnityEngine.Random.Range(zTerrainPos, zTerrainPos + terrainLength);
            float yVal = Terrain.activeTerrain.SampleHeight(new Vector3(randX, 0, randZ));

            //Apply Offset if needed
            yVal = yVal + yOffset;

            GameObject objInstance = (GameObject)Instantiate(prefab,
                new Vector3(randX, yVal, randZ), Quaternion.identity);

            if (duration > 0)
            {
                yield return new WaitForSeconds(duration);
            }
        }
    }
}

修改后的适配脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SpawnObjects : MonoBehaviour
{
    public GameObject prefab;
    // 拖拽场景中的山地模型到此处
    public GameObject mountainModel;
    public int numberOfObjects;
    public float duration;
    public float yOffset = 0.5f;
    // 可选:扩展生成范围边界,避免过度贴近模型边缘
    public float boundsExpand = 1f;

    private Bounds mountainBounds;


    void Awake()
    {
        Renderer mountainRenderer = mountainModel.GetComponent<Renderer>();
        if (mountainRenderer == null)
        {
            Debug.LogError("山地模型必须挂载Renderer组件,无法获取生成范围!");
            return;
        }
        mountainBounds = mountainRenderer.bounds;
        mountainBounds.Expand(boundsExpand);

        StartCoroutine(Generate());
    }

    IEnumerator Generate()
    {
        for (int i = 0; i < numberOfObjects; i++)
        {
            // 在山地包围盒范围内随机生成X、Z坐标
            float randX = Random.Range(mountainBounds.min.x, mountainBounds.max.x);
            float randZ = Random.Range(mountainBounds.min.z, mountainBounds.max.z);

            // 从山地上方发射向下射线,检测地表高度
            Ray ray = new Ray(new Vector3(randX, mountainBounds.max.y + 10f, randZ), Vector3.down);
            if (Physics.Raycast(ray, out RaycastHit hit, mountainBounds.size.y + 20f))
            {
                // 确保命中的是目标山地模型(可通过标签进一步过滤)
                if (hit.collider.gameObject == mountainModel)
                {
                    float yVal = hit.point.y + yOffset;
                    Instantiate(prefab, new Vector3(randX, yVal, randZ), Quaternion.identity);
                }
                else
                {
                    // 命中其他对象,重新生成坐标
                    i--;
                }
            }
            else
            {
                // 射线未命中,重新生成坐标
                i--;
            }

            if (duration > 0)
            {
                yield return new WaitForSeconds(duration);
            }
        }
    }
}

核心修改点
  • 替换依赖对象:移除Terrain变量,改用GameObject mountainModel,直接关联场景中的山地模型。
  • 基于包围盒确定生成范围:通过山地模型的Renderer.bounds获取X、Z轴的生成边界,替代原Terrain的尺寸计算逻辑。
  • 射线检测替代地形采样:用向下射线检测山地表面的方式获取Y轴坐标,取代Terrain.SampleHeight,适配模型地形。
  • 容错逻辑:当射线未命中山地或命中其他对象时,重新生成坐标,确保路点仅生成在山地表面。
  • 可选优化:通过boundsExpand调整生成范围,或给山地模型设置专属标签,在射线检测时通过hit.collider.tag精准过滤。

内容的提问来源于stack exchange,提问作者Daniel Lip

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 14:50:25