- Home /
Checking position
HI! Im new here, I need some advices, I have 1 spawner which spawn monsterns random on 9 spawnpoints at random time and my question is, How to check whether an object is created on a spawnpoint and if it is to stop creating another object on a spawnpoint.
Good day. Can you provide the code you are using? or you need to know how to spawn them?
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class Gnom$$anonymous$$enager : $$anonymous$$onoBehaviour {
public GameObject spawnThing;
public float spawnWait;
public float spawn$$anonymous$$ostWait;
public float spawnLeastWait;
public int startWait;
public bool stop;
public int endPoints;
public Transform[] spawnPoints;
public GameObject[] monsters;
int randomSpawnPoint, random$$anonymous$$onster;
public static bool spawnAllowed;
int randEnemy;
void Start()
{
StartCoroutine("SpawnObject");
}
void Update() { spawnWait = Random.Range(spawnLeastWait, spawn$$anonymous$$ostWait);
}
IEnumerator SpawnObject(){
yield return new WaitForSeconds(startWait);
while (Points.coin !=endPoints){
randomSpawnPoint = Random.Range(0, spawnPoints.Length);
random$$anonymous$$onster = Random.Range(0, monsters.Length);
Instantiate(monsters[random$$anonymous$$onster], spawnPoints[randomSpawnPoint].position,
Quaternion.identity);
yield return new WaitForSeconds(spawnWait);
}
}
void GameOver(){
if(Points.coin >= endPoints){
Debug.Log("End");
}
}
}
i want that if there is an object at a given point, so that it will not spawn twice
Answer by ModLunar · Jun 26, 2018 at 12:05 PM
A simple solution you could use is - create an array of booleans, the same size as your array of Transform[] of spawn points, so that each boolean in the boolean array corresponds to one of the spawn points, and keeps track of whether or not you spawned something at that particular spawn point.
You'd just need to make sure you set the booleans at the appropriate times to keep the booleans up to date (weird things will go wrong if you don't keep your variables up to date ;) )
Another possibility is to make a private (non-serialized, aka not shown in the inspector) List once your game starts. You can fill this list with all the spawn points initially. Then, you can pick one of the spawn points remaining in that list, and remove it once you use it. That way, what's left in the List is only the possible spawn points left over to be used up.
Wow I didn't think I'd be rambling on more! That List solution I thought of could actually be used with a Queue as well, if you put the spawn points into the Queue in a random order.
Anyway, the variables you would use would look something like this for the possible solutions I brought up:
//--- --- --- --- --- Boolean array solution:
//...
public Transform[] spawnPoints;
private bool[] alreadySpawned;
public void Awake() {
alreadySpawned = new bool[spawnPoints.Length];
//Nothing more to do, the boolean array initializes everything
//to default values (false for each boolean)
}
/*
When spawning from a random spawnPoint, you'll need to keep generating a new random index
and checking if you already spawned there until you finally generate a random index that hasn'that
been used up already.
*/
//--- --- --- --- --- List of Transforms solution:
//...
public Transform[] spawnPoints;
private List<Transform> spawnPointList; //List<T> is defined in System.Collections.Generic
public void Awake() {
spawnPointList = new List<Transform>(spawnPoints.Length);
for (int i = 0; i < spawnPoints.Length; i++)
spawnPointList.Add(spawnPoints[i]);
}
/*
You can then access spawnPointList with an indexer just like an array (ex: spawnPointList[i])
Each time you access something, you can then use spawnPointList.RemoveAt(i), where i is the 0-based integer index.
*/
//--- --- --- --- --- Queue solution:
//...
public Transform[] spawnPoints;
private Queue<Transform> spawnPointQueue; //Queue<T> is also in System.Collections.Generic
public void Awake() {
List<int> alreadyAdded = new List<int>(spawnPoints.Length);
//alreadyAdded is empty here, it just has the internal capacity to grow up to spawnPoints.Length
//without needing a (relatively) expensive resize operation.
//Create the Queue and add to it the spawn points in a random order :D
spawnPointQueue = new Queue<Transform>(spawnPoints.Length);
for (int i = 0; i < spawnPoints.Length; i++) {
int newIndex = Random.Range(0, spawnPoints.Length);
//Gotta make sure this new (randomly generated) index was not already added to the Queue
while (alreadyAdded.Contains(newIndex))
newIndex = Random.Range(0, spawnPoints.Length);
spawnPointQueue.Enqueue(spawnPoints[newIndex]);
}
}
/*
You can preview the first element in the Queue with spawnPointQueue.Peek(). This means you don't remove it from the Queue.
But when spawning, you'll probably want to take a spawn point and remove it from the Queue -- in which case,
you can make use of spawnPointQueue.Dequeue(), which returns the first element and removes it from the Queue!
*/
Answer by tormentoarmagedoom · Jun 26, 2018 at 11:45 AM
Good day.
I did this in one of my projects to be sure all random instantiated objects was at least 500 units away from others. (they was Spawn points)
I created my own detector. Just an EmptyObject with a collider and a script to detect all spawnpoints in a 500 units distance. Then sends a message to the Instantiating script if another spawnpoint was detected in a 500 units range. Then autodestroy itselfs.
So, if no "detection message" was received, is because there is no other spawnpoints there, so i can continue with the instantiate of the real object.
If another spawn was already there, just re-calculate the random point and commence again
:D
BYE!