【问题标题】:How can i spawn random objects that are not overlap between specific given area?如何生成在特定给定区域之间不重叠的随机对象?
【发布时间】:2017-10-15 09:19:03
【问题描述】:
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。 我有 wallStartPosition 例如 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!");
        }
    }
}

【问题讨论】:

    标签: c# unity3d unity5


    【解决方案1】:

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

    无论如何,根据您的目标最终结果,您必须编写这些对象在给定空间中的操作方式。例如,如果你有一个凌乱的房间作为场景,你可以有一张桌子,它会在两堵墙的角落找到空间,一张床靠一堵墙,垃圾随机产生。

    【讨论】:

      【解决方案2】:

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

      一旦你测试了这个条件并且它的评估结果为真,我建议你简单地移动重叠的对象,然后再针对场景中的其他对象进行测试。您可以通过仅测试您认为可能接近重叠或重叠的对象来变得聪明。

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

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

      提示:如果你让对撞机比物体大,你可以把物品放在一个最小的空间。例如,如果您有一个 localSize 1,1,1 的立方体 - 碰撞体的大小可以是 5,5,5,如果碰撞体重叠,Physics.OverlapSphere 将返回 true,要求立方体与彼此

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-04-01
        • 2022-07-13
        • 2011-07-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-19
        相关资源
        最近更新 更多