- Home /
Random Spawning system?
Hi,
I'm trying to devise a random but selective spawning system. I want to spawn objects in the level using a random int, but stop spawning a specific one after it has already been spawned a number of times. If it has already spawned, another object should be spawned instead.
Thanks for any and all suggestions!
//-------------------------
using UnityEngine;
using System.Collections;
public class Planet
{
public string name;
public Transform prefab;
public int number;
public Planet(string newName, Transform newPrefab, int newNumber)
{
name = newName;
prefab = newPrefab;
number = newNumber;
}
}
//--------------------------
void Awake()
{
//add to list
planets.Add ( new Planet("Start", start, 1));
planets.Add ( new Planet("End", end, 1));
planets.Add ( new Planet("Merchant", merchant, 1));
planets.Add ( new Planet("Poison", poison, poisonCount));
planets.Add ( new Planet("Repulse", repulse, repulsiveCount));
planets.Add ( new Planet("Money", money, moneyCount));
//Hex Grid spawning
float unitLength = ( useAsInnerCircleRadius )? (radius / (Mathf.Sqrt(3)/2)) : radius;
offsetX = unitLength * Mathf.Sqrt(3);
offsetY = unitLength * 1.5f;
for( int i = 0; i < spawnX; i++ )
{
for( int j = 0; j < spawnY; j++ )
{
Vector2 hexpos = HexOffset( i, j );
Vector3 pos = new Vector3( hexpos.x, hexpos.y, 0 );
if(planets.Count > 0)
Spawn(pos);
}
}
}
void Spawn(Vector3 position)
{
int planet = Random.Range (0, planets.Count);
//if the planet hasn't exceeded its spawn limit, spawn and count down...
if (CheckNumber(planet))
{
Instantiate (planets [planet].prefab, position, Quaternion.identity);
planets [planet].number --;
}
else
planets.Remove(planets[planet]);
}
bool CheckNumber(int index)
{
bool truth = planets[index].number > 0 ? true : false;
return truth;
}
int RandomNumber()
{
int number = Random.Range (0, planets.Count);
return number;
}
This is pretty hard to read, a switch inside of a switch? I would recommend getting rid of the ugly switch statements and create a proper data structure to hold the spawned prefabs (and possibly the prefabs that are capable of being spawned). You should take a look at the lists and dictionary tutorial here https://unity3d.com/learn/tutorials/modules/intermediate/scripting/lists-and-dictionaries
I keep repeating the same thing over and over. Collections are a very useful thing. Utilize them. Thank you @erebel55
Then You Have To maintain counter variable for each planet.. :)
@$$anonymous$$ehul Rughani
Your'e right, $$anonymous$$ehul. Iv'e again updated the code. Now it doesn't spawn if the counter has run out, but that leaves gaps in the level. How can I wait until the check has found a good object in the list to spawn, then resume?
Answer by zckhyt · May 27, 2015 at 12:20 PM
Okay, so I recommend that you either have a script that keeps track of the number of times a spawn-point has been use, or have this stored as a public integer (or otherwise have a getter method function that returns this). This counter, either way, should increment every time the GameObject is used to be the spawn-point. I'd put it in its own script just to keep things clean.
Then you have a couple of options (assuming these arrays don't have to be sorted in any way):
Sort the array every time a spawn-point is discovered to have spawned its limits to reflect this change. You would need to keep track of two integers: one containing the number of "good" spawn-points and one containing the original number.
Remove the GameObject from the array (optionally add it to another, separate array if you want to not destroy it). You would have to check to see if the index in the array points to null whenever you use it, though.
Keep trying to find a spawn-point until you find one that hasn't reached its maximum count, without removing or sorting anything. This is probably the easiest but the least efficient.
There are more options, but these are the ones that first pop into mind.
To find a random index (to find a random spawn-point) simply use Random.range(0, arraySize - 1);
Here is the basic implementation of the first possible solution (since it might sound a bit weird):
//Variables
bool spawnAvailable = true; //false when the object at index 0 can no longer spawn
bool sortedArray = false;
int limit = 5; //5 spawns per spawner
int SIZE = 10; //array will have 10 elements (indexes 0-9)
int numOfSpawners = SIZE - 1; //a non-const var to keep track of good spawn-points left
int index;
GameObject spawnPointArray[SIZE];
GameObject bufferObj;
//Spawning
index = Random.range(0, numOfSpawners);
if (spawnAvailable && spawnPointArray[index].GetComponent<SpawnCounterScript>().getSpawnCount() < limit)
{
//spawn from the spawn-point @ this index
}
else if (spawnPointArray[0].GetComponent<SpawnCounterScript>().getSpawnCount() > limit)
spawnAvailable = false;
else
{
while (sortedArray == false)
{
if (spawnPointArray[numOfSpawners].GetComponent<SpawnCounterScript>().getSpawnCount() < limit)
{
bufferObj = spawnPointArray[numOfSpawners];
spawnPointArray[numOfSpawners] = spawnPointArray[index];
spawnPointArray[index] = bufferObj;
sortedArray = true;
}
else
numOfSpawners--;
}
sortedArray = false; //reset variable
index = Random.range(0,numOfSpawners);
//spawn from the spawn-point @ this index
}
I know the sort could be more efficient, but I was making it simple to save space. One thing to note, if you want to access any of the spawners who exceeded the limit, you could get a random index containing one of them (assuming at least one) with Random.range(numOfSpawners, SIZE - 1);
Sorry this post was so long, but I felt complied to provide a code example of what I meant for the first point in case you actually wanted to use it (to provide a guideline). And hopefully I didn't mess anything up. So if you have any questions (or want to point out any mistakes in something that I totally proof-read...) let me know!
Your answer
Follow this Question
Related Questions
script not working pls solve it 1 Answer
How to save a scene that you randomly generated as a new level in your build settings? 1 Answer
Problem with Random.range 1 Answer
how can i do that enemy cars start coming up from my 2nd level of the game ? 1 Answer
How to Spawn multiple game object one by one in random order 1 Answer