Array or List, Index out of range, I've tried everything.. any other way of passing a list of values of an instantiated prefab to another script
So basically, I've set the List (tried with Array) filled it, works beautifully, but then when I try to either copy the whats inside the List into another script, or another function within the same script, no does the List act as though it is set, I always get an error, out of range, I tried approaching this from so many angles but still no success.. :/ Ultimately I'm just trying to find a way to pass the position of the instances I create from the prefab into the script of another prefab so that the AI code can track it, so unless there's a better way, this is the attempt I've got, any help is greatly appreciated.
using UnityEngine; using System.Collections; using System.Collections.Generic;
public class DotSpawner : MonoBehaviour {
float DotSpawnerTimer = 0f;
float BlobSpawnerTimer = 0f;
public GameObject Dots;
public GameObject Enemy;
int MaxBlobs = 0;
int MaxDots = 100;
public List<GameObject> Dot;
public GameObject Empty;
// Use this for initialization
void Start () {
Empty = new GameObject();
Dot = new List<GameObject>();
for (int a = 0; a < MaxDots; a++)
{
Dot.Add(Empty);
}
}
// Update is called once per frame
void FixedUpdate ()
{
DotSpawnerTimer -= Time.deltaTime;
if (DotSpawnerTimer <= 0)
{
CreateDots();
}
BlobSpawnerTimer -= Time.deltaTime;
if (BlobSpawnerTimer <= 0)
{
Instantiate(Enemy, new Vector3(Random.Range(-1.85f, 1.24f), Random.Range(0.1f, 2.41f), 0f), Quaternion.identity);
BlobSpawnerTimer = Random.Range(4f, 8f);
}
}
void CreateDots()
{
for (int a = 0, b = 0; a < MaxDots; a++)
{
if (Dot[a] == Empty || Dot[a] == null) // <=------- Accessing the list here works fine, but not in the function below, why?
{
GameObject DotCopy = Instantiate(Dots, new Vector3(Random.Range(-1.85f, 1.24f), Random.Range(0.1f, 2.41f), 0f), Quaternion.identity) as GameObject;
Dot[a] = DotCopy;
b++;
}
if (b >= 10)
{
DotSpawnerTimer = Random.Range(2f, 8f);
break;
}
}
}
public Vector3 Result;
public Vector3 GetDotLocation(Vector3 Blob)
{
for (int a = 0; a < MaxDots; a++)
{
if (Dot[a] != Empty || Dot[a] != null) // <=--------- This is where I get the error, out of range
{
Result.x = Dot[a].transform.position.x - Blob.x;
Result.y = Dot[a].transform.position.y - Blob.y;
Result.z = a;
break;
}
}
return Result;
}
bool DotStillActive;
public bool CheckDot(int DotIndex)
{
if (Dot[DotIndex] == null)
{
DotStillActive = false;
}
else if (Dot[DotIndex] != null)
{
DotStillActive = true;
}
return DotStillActive;
}
}
Thank you for your time
Answer by jgodfrey · Apr 20, 2016 at 11:02 PM
What calls GetDotLocation()? I assume it's being called from some other script? I'd guess it's being called before the Start() method (above) initializes your Dot list. If that's the case, you'll need to juggle some stuff around to ensure your list is initialized before GetDotLocation is called.
You could verify that it's a call order issue by placing a Debug.Log in the above Start() method as well as in the GetDotLocation() method. If you see the message from GetDotLocation() before the one in Start(), that's the issue.
Depending on where/when/how you're calling GetDotLocation(), the solution could be as simple as moving your Dot list initialization code from Start() to Awake().
Thank you for your speedy response, I tried as you said with the debug just now, seems to be working as should, Start() runs first, then followed by GetDotLocation(). But that's the thing, why would it work fine and I can access it no problem in void CreateDots(), but then when I try to extract a value from it to another script, it gives me grief.
I just want to simply pass the values in a List or array to another script, I've tried doing it the opposite way and calling a function from this script to fill the List or array in another script, when I do it that way, everything works fine in this script, but in the other script I get the same problem, even though it know i have made sure it is fully set up before using it. :/
why would it work fine and I can access it no problem in void CreateDots(), but then when I try to extract a value from it to another script, it gives me grief.
Well, since the call the CreateDots() is in the FixedUpdate() method of the same script, you're guaranteed that the Start() method will be called before CreateDots().
However, since GetDotLocation() is called from a different script (which you haven't shown), it's possible that script could call GetDotLocation() before the Start() method has had a chance to initialize the list. That's what I assume the problem was. However, if you have verified that your message from Start() is output before your message from GetDotLocation(), then I no longer think that's the issue.
What happens if you add this at the top of GetDotLocation()?
Debug.Log("Dots count: " + Dots.Count);
Oh okay, it's good to double check things. So I moved the initialize of Dot to Awake() just to make sure. (I'm noobish so didn't know about the function) but still didn't work. :/
So I tried to add "Debug.Log("Dots count: " + Dots.Count);" But it's not liking the "Count" at the end, saying "Unity does not contain the definition for "Count""
But I've tried before sticking "print(a);" just below for (int a = 0; a < $$anonymous$$axDots; a++) {
to see how many it goes through before error, give me an error on 0. :/
I can only assume that something else (somewhere else) is modifying the public Dot list. A few questions:
Does Dot need to be public? If not, make it private to ensure it can't be changed elsewhere.
If yes, why? And, where else is it being accessed?
No, it's not being accessed anywhere else, it was in my other me method, but not in this one. Just tried it now with private though, but still the same. :/
Is there a better way, or another way of storing the instantiated prefabs positions, and passing them to another script, or different methods of passing arrays as a whole or lists as a whole to another script. $$anonymous$$y previous method was this:
first create
public Enemy enemy;
void CreateDots()
{
for (int a = 0, b = 0; a < $$anonymous$$axDots; a++)
{
if (Dot[a] == Empty || Dot[a] == null)
{
GameObject DotCopy = Instantiate(Dots, new Vector3(Random.Range(-1.85f, 1.24f), Random.Range(0.1f, 2.41f), 0f), Quaternion.identity) as GameObject;
Dot[a] = DotCopy;
enemy.PassDotLocation(DotCopy, a); // <==------ Pass Value
then in the other script:
void PassDotLocation(GameObject Dot, int Index)
{
Dots[Index] = Dot; <==------- And I made sure the Dots() was initialize before use but I would get the same problem just here ins$$anonymous$$d, I just can't seem to pass the value :S
}