用Unity C#在某一点周围随机生成游戏对象

3

我不确定如何解决这个问题,或者是否有任何内置的Unity函数可以帮助解决这个问题,所以非常感谢您提供任何建议。

下面是一张图片,将有助于描述我的要求: enter image description here

我想在给定点周围的半径范围内生成游戏对象。然而,它们在半径范围内的位置应该是随机选择的。这个位置应该与原点(在地面上)具有相同的Y轴。下一个主要问题是每个物体都不应该与其他游戏对象重叠,并且不应该进入它们的个人空间(橙色圆圈)。

到目前为止,我的代码还不太好:

public class Spawner : MonoBehaviour {

    public int spawnRadius = 30; // not sure how large this is yet..
    public int agentRadius = 5; // agent's personal space
    public GameObject agent; // added in Unity GUI

    Vector3 originPoint;    

    void CreateGroup() {
        GameObject spawner = GetRandomSpawnPoint ();        
        originPoint = spawner.gameObject.transform.position;        

        for (int i = 0; i < groupSize; i++) {           
            CreateAgent ();
        }
    }

    public void CreateAgent() {
        float directionFacing = Random.Range (0f, 360f);

        // need to pick a random position around originPoint but inside spawnRadius
        // must not be too close to another agent inside spawnRadius

        Instantiate (agent, originPoint, Quaternion.Euler (new Vector3 (0f, directionFacing, 0f)));
    }
}

感谢您能提供的任何建议!

在圆形区域内生成不是问题,但为什么你不使用碰撞器来维护空间呢? - Hamza Hasan
@HamzaHasan - 我不是很确定从哪里开始。使用碰撞器来检测另一个代理进入另一个代理的个人区域可能是一个好主意,但是如何将它们分离?目前每个代理都不会移动。我只想在它们生成时在有效的位置生成它们,但我不确定碰撞器如何帮助我实现这一点。 - Mayron
好的,让我来处理一下,告诉我你是在使用2D还是3D? - Hamza Hasan
哇,非常感谢。它是三维的 :) - Mayron
让我来写你的答案 :) - Hamza Hasan
2个回答

7

为了避免重叠,您可以使用碰撞器(colliders)来创建个人空间。

如果要生成圆形,请使用Random.insideUnitSphere。您可以修改您的方法如下:

 public void CreateAgent() {
        float directionFacing = Random.Range (0f, 360f);

        // need to pick a random position around originPoint but inside spawnRadius
        // must not be too close to another agent inside spawnRadius
        Vector3 point = (Random.insideUnitSphere * spawnRadius) + originPoint;
        Instantiate (agent, point, Quaternion.Euler (new Vector3 (0f, directionFacing, 0f)));
    }

希望这能帮到您。

啊,那很简单。非常感谢。我决定使用NavMeshAgent,因为它具有自动确保敌人不会相互碰撞的能力,而不是使用碰撞器。希望这样能行。 - Mayron
哥们,你在问题中可以明确一下你需要那种东西:D - Hamza Hasan
我主要在敌人生成后使用NavMeshAgent。不幸的是,它不能自动将它们移动到正确的位置。 - Mayron
顺便说一下,我刚刚才想到要添加那个 ^^ - Mayron

6

为了在圆形范围内生成对象,您可以定义生成器的半径,并将介于 -radius 和 radius 之间的随机数添加到生成器的位置,如下所示:

float radius = 5f;
originPoint = spawner.gameObject.transform.position;
originPoint.x += Random.Range(-radius, radius);
originPoint.z += Random.Range(-radius, radius);

检测生成点是否太靠近其他游戏对象,可以通过以下方式检查它们之间的距离:
if(Vector3.Distance(originPoint, otherGameObject.transform.position < personalSpaceRadius)
{
    // pick new origin Point
}

对于Unity3D,我并不是很熟练,所以可能无法给出最好的答案,请见谅^^

此外:

要检查哪些gameobject实际在生成区域内,您可以使用在此处定义的Physics.OverlapSphere函数: http://docs.unity3d.com/ScriptReference/Physics.OverlapSphere.html


那绝对帮了我很多,谢谢。我一直在考虑随机选择生成位置,直到它们不重叠,但这样会非常浪费处理资源,因为如果我意外地使生成半径太短,它可能会很难找到一个好的位置。我会去查看那个函数的 :) - Mayron

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接