- Home /
Trying to use lists to check for available spawn points
I'm trying to use lists to check for available spawn points and to select the spawn point to use. To do this I made a list called EnemySpotsAvailable and a list called EnemySpotsHeld. These lists hold the values for the spawn points on the X and Z axis.
public class EnemySpotsAvailable : MonoBehaviour
{
public int pointX;
public int pointZ ;
public EnemySpotsAvailable(int newPointX, int newPointZ)
{
pointX = newPointX;
pointZ = newPointZ;
}
}
public class EnemySpotsHeld : MonoBehaviour
{
public int pointX;
public int pointZ;
public EnemySpotsHeld(int newPointX, int newPointZ)
{
pointX = newPointX;
pointZ = newPointZ;
}
}
In my EnemySpawn class I'm trying to use these lists to decide on where the enemy can spawn. I'm trying to use Random.Range()
to choose an index number from the EnemySpotsAvailable list. When it has chosen an index number I want to copy the value in pointX to spawnX and copy the value in pointY to spawnY. After I've done this I want to remove this index from EnemySpotsAvailabe and move it to EnemySpotsHeld. I feel like I'm overlooking something really simple but I'm just unable to figure it out.
public class EnemySpawn : MonoBehaviour
{
public GameObject Enemy;
int[] spawnRange = new int[] { -4, 0, 4 };
int spawnX = 0;
int spawnZ = 0;
List<EnemySpotsAvailable> spotsAvailable = new List<EnemySpotsAvailable>();
List<EnemySpotsHeld> spotsHeld = new List<EnemySpotsHeld>();
void Start()
{
foreach (int x in spawnRange)
{
foreach (int z in spawnRange)
{
spotsAvailable.Add(new EnemySpotsAvailable(x, z));
}
}
foreach(EnemySpotsAvailable spot in spotsAvailable)
{
print(spot.pointX + " + " + spot.pointZ);
}
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
SpawnEnemy();
}
}
public void SpawnEnemy()
{
ChooseSpawn();
Instantiate(Enemy, new Vector3(spawnX, 5, spawnZ), Quaternion.identity);
Debug.Log("X= " + spawnX + " Z= " + spawnZ);
}
private void ChooseSpawn()
{
int randomIndex = Random.Range(0, spotsAvailable.Count);
//Beyond this point I'm unsure on what to do
spawnX = 0;
spawnZ = 0;
}
}
Answer by DanielGL · Feb 08 at 01:40 PM
We have a few things to look down...
1-Classes which inherit from MonoBehaviour shouldn't have constructor methods, i'm pretty shure you want to remove this inheriterance in both classes "EnemySpotsAvailable " and "EnemySpotsHeld";
2-Those classes "EnemySpotsAvailable " and "EnemySpotsHeld" are redundant, I would suggest you to switch that for two Vector3Int lists;
3-To spawn with those points, it would be like that:
List<Vector3Int> spotsAvailable = new List<Vector3Int>();
List<Vector3Int> spotsHeld = new List<Vector3Int>();
private Vector3Int ChooseSpawn()
{
int randomIndex = Random.Range(0, spotsAvailable.Count);
Vector3Int spot = spotsAvailable[randomIndex ];
spotsAvailable.RemoveAt(randomIndex);
spotsHeld.Add(spot);
return spot;
}
public void SpawnEnemy()
{
Vector3Int spawnPoint = ChooseSpawn();
Instantiate(Enemy, new Vector3(spawnPoint .x, 5, spawnPoint.z), Quaternion.identity);
Debug.Log("X= " + spawnX + " Z= " + spawnZ);
}
Thank you so much this was exactly what I needed. I didn't realize it could be this simple
Answer by Captain_Pineapple · Feb 08 at 01:50 PM
Hey,
basically first thing to do would be to remove the differentiation between EnemySpotsAvailable
and EnemySpotsHeld
.
You keep the same data in there so give it a name that fits it's purpose: To keep data that defines a spawnpoint.
So do somethig like:
public class SpawnPoint : MonoBehaviour // check if this really is needed to be a Monobehaviour here
{
public int pointX;
public int pointZ;
public SpawnPoint(int newPointX, int newPointZ)
{
pointX = newPointX;
pointZ = newPointZ;
}
}
At this point please check if you really need this to be a Monobehaviour
. If you do not have a need to attach this script to a gameobject and want to create new objects of this type using new
then you have to remove the Monobehaviour
inheritance.
Apart from that you can then just write:
private SpawnPoint ChooseSpawn()
{
int randomIndex = Random.Range(0, spotsAvailable.Count);
//get the chosen spawn from the list:
var chosenSpawn = availableSpawns[randomIndex];
//remove it from availableSpawns:
availableSpawns.Remove(chosenSpawn);
//add it to the "held" spawns:
heldSpawns.Add(chosenSpawn);
//return the spawn:
return chosenSpawn;
}
And change your Spawn function to:
public void SpawnEnemy()
{
var newSpawn = ChooseSpawn();
Instantiate(Enemy, new Vector3(newSpawn.newPointX, 5, newSpawn.newPointY), Quaternion.identity);
//.....
}
Be aware that this will currently not free any spawns again. For this it might be good to give your enemy a reference to the spawnpoint so that if it moves away from the spawn it can call a function on your spawnmanager where it gives the point it spawned on as a reference from which you can move it to the correct list again.
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
How do I check if a spot in a cell is missing? 2 Answers
Learn C# In General Or Learn It With Unity? 1 Answer
Movement using the Scrollbar 1 Answer
Question on UnityScript and C# 1 Answer