How to access array inside another array?
Hello,
I'm trying to create a tower defense game that has multiple paths on each level. The example I'm using is Kingdom Rush. In that game, mobs will spawn from different points and follow a set path.
When my units spawn, they get a waypoint assigned and follow that path. My problem is, I can only assign a gameobject from the top array. Unity doesn't seem to support Arrays within Arrays in the inspector. I know there are workarounds, but they seem convuluted. This works in the tutorial that I was following, but what I'd like to do is have more than one path. My approach is to have an array of paths that contain an array of waypoints. I would then assign the waypoint that is in the spawnpoint array, but I can't get the value contained in the Spawn points array. If I create a multidimensional array, I can't access it in the inspector. If I write this: newEnemy.GetComponent<Unit_Base>().waypoints = waves[currentWave].spawnPoints[2];
I get the error saying that spawpoints cannot be used because it is an array, and my assignment is expecting a gameobject.
What is a better approach? How do I access the values of an Array within another array?
Here is my code for refference. Please let me know if anything needs clarifying
using UnityEngine;
using System.Collections;
[System.Serializable]
public class Wave
{
public GameObject[] spawnPoints;
public GameObject[] enemyPrefab;
public GameObject[] waypoints;
// HACK 9-12 DOESNT WORK
public float spawnInterval = 2;
public int maxEnemies = 20;
}
public class SpawnEnemy : MonoBehaviour {
public Wave[] waves; //class object
//9-13 spawn point example
public int timeBetweenWaves = 5;
private float lastSpawnTime;
private int enemiesSpawned = 0;
public GameManager gameManager; //Find the game manager class
// Use this for initialization
void Start ()
{
lastSpawnTime = Time.time;
gameManager = GameObject.Find("GameManager").GetComponent<GameManager>();
}
public void Update()
{
int currentWave = gameManager.Wave;
//Check to make sure enemies are left
if (currentWave < waves.Length)
{
// 2
float timeInterval = Time.time - lastSpawnTime;
float spawnInterval = waves[currentWave].spawnInterval;
if (((enemiesSpawned == 0 && timeInterval > timeBetweenWaves) ||
timeInterval > spawnInterval) &&
enemiesSpawned < waves[currentWave].maxEnemies)
{
lastSpawnTime = Time.time;
Vector3 startPos = GameObject.Find("Waypoint0").GetComponent<Transform>().position; //Get the position of the first spawn point in the level
GameObject newEnemy = (GameObject)Instantiate(waves[currentWave].enemyPrefab[Random.Range(0,waves[currentWave].enemyPrefab.Length)], startPos, Quaternion.identity); //Spawn a random enemy
newEnemy.GetComponent<Unit_Base>().waypoints = waves[currentWave].spawnPoints[2]; // waypoints; //Set the waypoint of the enemy
//
//need to make two choices
enemiesSpawned++; //add to enemies spawned
}
// Check to see if the last enemeis have been spawned in current wave
//If they have,
if (enemiesSpawned == waves[currentWave].maxEnemies &&
GameObject.FindGameObjectWithTag("Enemy") == null)
{
gameManager.Wave++; //increase to wave
enemiesSpawned = 0;
lastSpawnTime = Time.time;
}
} else{
//If no more enemies, and player still has lives call the win function load next level
gameManager.gameOver = true;
}
}
}
In order to understand your question properly, clarify this for me: you have assigned some spawnPoints Gameobjects in editor and you are trying to assign them to your newEnemy's waypoints, which is an array. So each of your spawnPoints contains some waypoints within, and you want to assign one spawnPoint's every waypoint it contains directly to your newEnemy's waypoints. Am I correct?
Yes that's exactly correct. The spawnpoint gameobjects have a one line script that is a public array of GameObjects. The waypoints are just empty gameobjects and are assigned to this array.
I want to assign these waypoints to newEnemy's waypoints variable.
In your class definition of spawnPoints public GameObject[] spawnPoints
waves[currentWave].spawnPoints[2]
will return a GameObject. So the question is, how is Unit_Base.waypoints
defined as seen below
newEnemy.GetComponent<Unit_Base>().waypoints
If Unit_Base.waypoints
is an array then you will get an error because you are trying to assign a GameObject waves[currentWave].spawnPoints[2]
to an array Unit_Base.waypoints
.
The thing is do you want to assign a single object as you are doing here
waves[currentWave].spawnPoints[2]
or do you want to assign the whole array
waves[currentWave].spawnPoints
Answer by Vandarthul · Sep 14, 2016 at 08:00 PM
As I understand your project setup is like this, roughly:
If you want to allocate a collection of waypoints to newEnemy's waypoint you need to do this:
newEnemy.GetComponent<Unit_Base>().waypoints = waves[currentWave].spawnPoints[2].GetComponent<Waypoints>().waypoints;
In order to explain things, you are trying to cast a gameObject into array of gameObjects which will cause error. You need to reach a single spawnPoint's collection of waypoints and assign it to our newEnemy's waypoints.
So what you are doing was: trying to assign a GameObject into GameObject[] > gives error because its not covenient.
What you need to do: assign a GameObject[] into GameObject[] > like previous example I gave.
I hope this helps.
Thanks @vandarthul!
I'll ry thia when I'm home tonight. I did try to use the '.GetComponent' method by typing:
waves[currentWave].spawnpoints.GetComponent<Waypoints>() ...
I got an error saying that spawnpoints did not contain this method. I know hay spawnpoints is the collection itself, but was my error not referencing an index? (an element in the array)
Yes, you can't get a component from array, only way to get it is waves[currentWave].spawnpoints[0].GetComponent() because GetComponent looks for GameObject, not GameObject[].