在地图中生成随机游戏对象(无重复)

Spawning random GameObject in map (no repetitions)

我正在制作一个恐怖游戏,我想在我的场景中生成一些小收藏品,我的代码工作正常,但它们在每个实例化时都会重复世界位置:

using UnityEngine;

public class objectivesGeneration : MonoBehaviour
{
    GameObject[] objSpawn;
    GameObject objActual;
    public GameObject obj;
    int index;
    void Start()
    {
        objSpawn = GameObject.FindGameObjectsWithTag("spawnObj");
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.I))
        {
            generateNewObj();
        }
    }

    public void generateNewObj()
    {
        index = Random.Range(0, objSpawn.Length);
        objActual = objSpawn[index];
        createObj();
    }
    public void createObj()
    {
        
        Instantiate(obj, objActual.transform.position, objActual.transform.rotation);
    }
}

有人可以帮我吗?

您正在同一位置生成对象objActual.transform.position

您应该使用 2 个变量设置出生点的限制,例如:

public float startx;
public float endx;
public float starty;
public float endy;

然后就可以很方便的在这个位置随机实例化了:

float posX = Random.Range(startx, endx);
float posy = Random.Range(starty, endy);
Instantiate(obj, new Vector3(posx, posy, transform.position.z, Quaternion.Identity);

所以你有一个随机生成!

你的问题可以从两个方面来理解。 Leoverload给出了重复位置的答案。 如果您不想重复相同类型的对象(因此所有对象都是唯一的),请执行以下操作:

  1. 将 objSpawn 变成一个 List<GameObject> 变量,并在 start() 函数中,添加从 FindGameObjectsWithTag 返回的数组中的所有实例。
  2. objSpawn.Length 变成 objSpawn.Count (除了列表之外,效果相同) 在同一个函数中,最后添加:objSpawn.Remove(objActual)。 如果这些对象在某个时候被销毁并且您想要创建被销毁对象的新实例,请确保在它们的 Destroy 事件中,您再次 Add(gameObject) 到列表中。

我给你的是说明,而不仅仅是代码,这样你以后就可以自己学习了。

另外,我觉得您需要了解 arguments\parameters 的工作原理。然后您可以省略该 objActual 变量,而是将对象直接传递给 createObj(GameObject theObj)

感谢 AlexGeorg 的回答, 这就是我的最终代码

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

public class objectivesGeneration : MonoBehaviour
{
    public GameObject recipient;

    public List<GameObject> objSpawns = new List<GameObject>();
    int spawnSelected;


    void Start()
    {
        //Set all the objs with the tag spawnLocation inside of the list
        foreach (GameObject OBJ in GameObject.FindGameObjectsWithTag("spawnLocation"))
        {
            objSpawns.Add(OBJ);
        }
    }
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.I))
        {
            //Check if there are more possible spawns
            if (objSpawns.Count > 0)
            generateNewObj(recipient);
        }
    }

    public void generateNewObj(GameObject frasco)
    {
        //Get a random number of the list which contains one obj
        spawnSelected = Random.Range(0, objSpawns.Count);
        //Instantiate the GameObject in the location of the random selected object
        Instantiate(frasco, objSpawns[spawnSelected].transform.position, objSpawns[spawnSelected].transform.rotation);
        //Delete that possible location from the list
        objSpawns.RemoveAt(spawnSelected);
    }
}