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

Unity地形动物随机生成异常:如何让动物始终生成在地面?

问题

我编写了一个随机生成动物的脚本,但当前动物会生成在山丘内部(我的地形包含大量山丘)。我希望实现动物始终在地面生成的效果。注:我的地形Y轴数值通常为0。当前代码如下:

IEnumerator spawnenemiesatposition1()
{
yield return new WaitForSeconds(3f);
while (cond1)
{
    Vector3 position1 = new Vector3(Random.Range(5, 195), 1, Random.Range(5, 495));
    Instantiate(Deer, position1, Quaternion.Euler(-90, 0, 0));
    deernum1++;
    if (deernum1 > 5)
    {
        cond1 = false;
    }

}

解决方法

方式一:通过Terrain组件获取地面高度

如果使用Unity内置Terrain,直接调用SampleHeight方法获取指定X/Z坐标对应的地面Y值,调整生成位置即可:

IEnumerator spawnenemiesatposition1()
{
    yield return new WaitForSeconds(3f);
    while (cond1)
    {
        float x = Random.Range(5, 195);
        float z = Random.Range(5, 495);
        // 获取该位置的地形高度
        float groundY = Terrain.activeTerrain.SampleHeight(new Vector3(x, 0, z));
        // 加上地形自身的Y轴偏移(若地形有整体位移)
        groundY += Terrain.activeTerrain.transform.position.y;
        // 给动物添加高度偏移,避免模型卡进地面,数值按需调整
        Vector3 position1 = new Vector3(x, groundY + 0.5f, z);
        Instantiate(Deer, position1, Quaternion.Euler(-90, 0, 0));
        deernum1++;
        if (deernum1 > 5)
        {
            cond1 = false;
        }
    }
}

方式二:射线检测定位地面

如果地形包含自定义碰撞体(比如非内置Terrain的模型),用向下射线检测找到地面碰撞点:

IEnumerator spawnenemiesatposition1()
{
    yield return new WaitForSeconds(3f);
    while (cond1)
    {
        float x = Random.Range(5, 195);
        float z = Random.Range(5, 495);
        // 从高处向下发射射线,覆盖足够检测范围
        Vector3 rayOrigin = new Vector3(x, 20, z);
        Ray groundCheckRay = new Ray(rayOrigin, Vector3.down);
        
        if (Physics.Raycast(groundCheckRay, out RaycastHit hitInfo, 30f))
        {
            // 以碰撞点Y坐标为基准,添加模型偏移
            Vector3 position1 = new Vector3(x, hitInfo.point.y + 0.5f, z);
            Instantiate(Deer, position1, Quaternion.Euler(-90, 0, 0));
            deernum1++;
            if (deernum1 > 5)
            {
                cond1 = false;
            }
        }
        else
        {
            // 未检测到地面时跳过本次生成,重新随机坐标
            continue;
        }
    }
}
  • 注意给地面添加有效碰撞体(如TerrainCollider或MeshCollider),确保射线能正确检测到地面。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 02:50:33