如何生成在特定给定区域之间不重叠的随机对象?

时间:2017-10-14 21:31:22

标签: c# unity3d unity5

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

public class WallsTest : MonoBehaviour
{
    // using a GameObject rather than a transform
    public GameObject prefab;
    public Vector3 wallsStartPosition;
    public float width = 0;
    public float height = 1;
    public float length = 2;
    public Camera wallsCamera;
    public float wallsArea;

    void Start()
    {
        wallsCamera.transform.position = new Vector3(wallsStartPosition.x, wallsStartPosition.y + 100, wallsStartPosition.z - 235);

        BuildWalls();
    }

    private void Update()
    {

    }

    void BuildWalls()
    {
        for (int i = -2; i < 2; i++)
        {
            GameObject go = Instantiate(prefab);
            go.transform.parent = transform;
            Vector3 scale = Vector3.one;
            Vector3 adjustedPosition = wallsStartPosition;

            float sign = Mathf.Sign(i);
            if ((i * sign) % 2 == 0)
            {
                adjustedPosition.x += (length * sign) / 2;
                scale.x = width;
                scale.y = height;
                scale.z *= length + width;
            }
            else
            {
                adjustedPosition.z += (length * sign) / 2;
                scale.x *= length + width;
                scale.y = height;
                scale.z = width;
            }

            adjustedPosition.y += height / 2;
            go.transform.localScale = scale;
            go.transform.localPosition = adjustedPosition;
        }
    }
}

例如,长度为100,所以我认为面积将是100x100。 我有wallsStartPosition例如250,0,250

现在我希望在墙壁区域内实例化随机位置的对象数量。例如50个立方体。但是它们不应该相互重叠,例如,彼此之间的最小间隙应该是5.并且最大间隙可以是它。

但我还不了解如何计算墙壁的面积和位置,只是在里面实例化随机物。

这是在给定区域中随机位置产生游戏对象的脚本。在这种情况下,该区域是地形。但我希望该区域位于我在第一个脚本中创建的墙内。此脚本附加到与WallsTest脚本相同的空游戏对象。

SpawnObjects脚本的另一个问题是对象之间的间隙没有任何设置,如果对象太好,比如20,20,20,那些在边缘产生的一半对象会在地形之外。

spawn

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

public class SpawnObjects : MonoBehaviour
{
    public Terrain terrain;
    public int numberOfObjects; // number of objects to place
    private int currentObjects; // number of placed objects
    public GameObject objectToPlace; // GameObject to place
    private int terrainWidth; // terrain size (x)
    private int terrainLength; // terrain size (z)
    private int terrainPosX; // terrain position x
    private int terrainPosZ; // terrain position z
    void Start()
    {
        // terrain size x
        terrainWidth = (int)terrain.terrainData.size.x;
        // terrain size z
        terrainLength = (int)terrain.terrainData.size.z;
        // terrain x position
        terrainPosX = (int)terrain.transform.position.x;
        // terrain z position
        terrainPosZ = (int)terrain.transform.position.z;
    }
    // Update is called once per frame
    void Update()
    {
        // generate objects
        if (currentObjects <= numberOfObjects)
        {
            // generate random x position
            int posx = Random.Range(terrainPosX, terrainPosX + terrainWidth);
            // generate random z position
            int posz = Random.Range(terrainPosZ, terrainPosZ + terrainLength);
            // get the terrain height at the random position
            float posy = Terrain.activeTerrain.SampleHeight(new Vector3(posx, 0, posz));
            // create new gameObject on random position
            GameObject newObject = (GameObject)Instantiate(objectToPlace, new Vector3(posx, posy, posz), Quaternion.identity);
            newObject.transform.localScale = new Vector3(20, 20, 20);
            currentObjects += 1;
        }
        if (currentObjects == numberOfObjects)
        {
            Debug.Log("Generate objects complete!");
        }
    }
}

2 个答案:

答案 0 :(得分:0)

我的技术知识有限,但您必须让脚本每[X]个位置生成这些对象(&#34; posX + = 1.0f;&#34;或者其他东西)为了使它们以统一的方式出现,或者让脚本记录每个新对象的位置,并使用该信息来计算远离所述对象的空间以产生另一个对象。

在任何情况下,根据您的目标最终结果,您必须编写这些对象在给定空间中的运行方式。例如,如果你有一个凌乱的房间作为一个场景,你可以有一个桌子,在两面墙的角落找到空间,一面墙和一面墙,垃圾随机产卵。

答案 1 :(得分:0)

您可以使用Physics.OverlapSphere来测试两个对象是否重叠。这假设对象都有碰撞器。

一旦你测试了这个条件并且它的计算结果为true,我建议只需移动重叠的对象并再次对照场景中的其他对象进行测试。通过仅测试您认为可能接近重叠或重叠的对象,您可以巧妙地做到这一点。

或者,您可以将每个对象与场景中的每个其他对象进行比较。如果您有很多对象,这将不是理想的,因为这样做会O(n^2)复杂。

在任何情况下,您都可以使用此功能测试重叠。祝你好运。

提示:如果使对手比对象大,则可以将物品放置在最小间距。例如,如果你有一个localSize 1,1,1的立方体 - 如果碰撞器重叠,则colider可以是5,5,5并且Physics.OverlapSphere将返回true,要求立方体是一个某些空间彼此分开