简体   繁体   English

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

[英]How can i spawn random objects that are not overlap between specific given area?

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;
        }
    }
}

For example the length is 100 so the area will be 100x100 i think. 例如长度是100,所以我认为面积将是100x100。 And i have the wallsStartPosition for example 250,0,250 我有wallsStartPosition例如250,0,250

Now i want inside the walls area to instantiate at random position number of objects. 现在我想在墙壁区域内实例化对象的随机位置数。 For example 50 cubes. 例如50个立方体。 But they should not be overlap each other and for example the minimum gap between each other should be 5. and maximum gap as fas it can be. 但是它们不应彼此重叠,例如彼此之间的最小间隙应为5.,最大间隙应尽可能地大。

But i don't understand yet how to calculate the area and position of the walls and just instantiate random objects inside. 但是我还不了解如何计算墙壁的面积和位置以及仅实例化内部的随机对象。

And this is the script for spawning gameobjects at random positions in given area. 这是用于在给定区域中的随机位置生成游戏对象的脚本。 In this case the area is the terrain. 在这种情况下,该区域是地形。 But i want the area to be inside the walls i create in the first script. 但是我希望该区域在我在第一个脚本中创建的墙内。 This script is attached to the same empty gameobject like the WallsTest script. 该脚本与WallsTest脚本一样附加到相同的空游戏对象。

Another problem with the SpawnObjects script is that there is no any set for the gap between the objects and if the objects too good like scale 20,20,20 some of the objects that spawn on the edge half out of the terrain. 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!");
        }
    }
}

My technical knowledge is limited, but you'll have to either get the script to spawn these objects every [X] amount of position ("posX += 1.0f;", or something to that effect) so that they appear in a uniform manner, or, have the script record each new object's position and use that information to calculate space away from said objects to spawn another one. 我的技术知识有限,但您必须获得脚本以每[X]个位置数量生成这些对象(“ posX + = 1.0f;”或类似的操作),以便它们统一显示或者,让脚本记录每个新对象的位置,并使用该信息来计算远离所述对象的空间以生成另一个对象。

In any case, depending on the end result you're aiming for, you'll have to write how these objects operate in a given space. 无论如何,根据最终目标,您必须编写这些对象在给定空间中的工作方式。 For example, if you have a messy room as a scene, you can have one desk that would find space in the corner of two walls, one bed alongside one wall and rubbish spawning randomly. 例如,如果您有一个凌乱的房间作为场景,则可以有一张桌子可以在两堵墙的角落找到空间,一张床和一堵墙相邻,并且可以随机产生垃圾。

You can use Physics.OverlapSphere to test if two objects are overlapping. 您可以使用Physics.OverlapSphere来测试两个对象是否重叠。 This assumes that the objects both have colliders. 假定对象都具有碰撞器。

Once you test this condition and it evaluates to true, I would suggest simply moving the object that overlaps and testing it again against the other objects in the scene. 一旦测试了这种情况并且评估结果为true,我建议您简单地移动重叠的对象,然后针对场景中的其他对象再次进行测试。 You can get clever with this by only testing objects you think might be close to overlapping, or overlapping. 通过仅测试您认为可能接近重叠或重叠的对象,您可以对此变得更聪明。

Alternatively you can just compare every object to every other object in the scene. 或者,您可以仅将每个对象与场景中的每个其他对象进行比较。 This would not be ideal if you have a lot of objects, because doing so would be O(n^2) complexity. 如果您有很多对象,这将不是理想的选择,因为这样做的复杂度为O(n^2)

In any case you can use this function to test overlapping. 无论如何,您都可以使用此功能测试重叠。 Good luck. 祝好运。

hint: if you make the collider bigger than the object, you can place items a minimum space apart. 提示:如果使碰撞器比对象大,则可以将项目放置在最小距离处。 For example if you have a cube of localSize 1,1,1 - the colider can be 5,5,5 in size and Physics.OverlapSphere will return true if the colliders overlap, demanding that the cubes be a certain space apart from each other 例如,如果你有一个立方体localSize 1,1,1 -在colider可以5,5,5的大小和Physics.OverlapSphere将返回true,如果对撞机重叠,要求立方体彼此一定的空间间隔

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM