- Home /
Creating an array of prefabs?
So I'm making a game that takes place in a forest, and at the beginning I call a script to populate the scene with trees. The trees are prefabs I made that have a function for setting on fire (and spreading fire to the other trees). I'd like to store all the trees in a 2-dimensional array (they're arranged in a grid), however when I try to do that, I get an error of "Cannot implicitly convert type UnityEngine.Object' to
UnityEngine.Transform'".
I sampled some code below that's supposed to create a 10x10 grid of trees, and set the one at (5,5) on fire using the Activate() function. Can anyone explain what I'm doing wrong?
public Transform tree;
Transform[][] forest;
void Start () {
for (int i = 0; i < boardWidth; i++)
{
for (int j = 0; j <boardHeight; j++)
{
forest[i][j]=Instantiate(tree, new Vector3(i*tileWidth, 0, j*tileHeight), Quaternion.identity);
if (i == 5 && j==5){
tree.GetComponent<TreeScript>().Activate();
}
}
}
}
I always have trouble with instantiation like that unless I use some kind of casting, try something like this:
forest[i][j] = (Transform) Instantiate(...);
Interesting, now it compiles, but it says NullReferenceException: Object reference not set to an instance of an object.
EDIT: Turns out I was declaring the array wrong. D'oh!
Answer by Visal · Dec 17, 2013 at 04:23 AM
To avoid "Cannot implicitly convert type UnityEngine.Object' toUnityEngine.Transform'" you need to cast the instantiate object to Transform object. This should do the trick
forest[i][j] = (Transform)Instantiate(tree, new Vector3(i*tileWidth, 0, j*tileHeight), Quaternion.identity);
And for the NullReferenceException I guess because you try to get component from the prefab Tree which is not active in the Hierarchy (or still in the asset folder I guess) plus the tree object is not equal to forest at (5,5) that you want to set on fire. So to fix that I think you should use this
forest[i][j].GetComponent<TreeScript>().Activate();//i and j both equal to 5 according to the condition you use
Her is the full code:
public Transform tree;
Transform[][] forest;
void Start () {
for (int i = 0; i < boardWidth; i++)
{
for (int j = 0; j <boardHeight; j++)
{
forest[i][j] = (Transform)Instantiate(tree, new Vector3(i*tileWidth, 0, j*tileHeight), Quaternion.identity);
if (i == 5 && j==5){
forest[i][j].GetComponent<TreeScript>().Activate();//i and j both equal to 5
}
}
}
}
Hope that could help and sorry about my grammar I'm not really good at English :)
Yup, that was the other half! So yeah, I was declaring the array incorrectly, and then I did need to cast it when I instantiated. Thanks!
Answer by YoungDeveloper · Dec 17, 2013 at 01:45 AM
Instead of creating free as Transform, try GameObject
Unfortunately, it gives me the same error, except ins$$anonymous$$d of saying it can't convert UnityEngine.Object' to UnityEngine.Transform, it says UnityEngine.GameObject ins$$anonymous$$d...
Answer by Kiloblargh · Dec 17, 2013 at 02:42 AM
You have to dimension an array before you can fill it. Unfortunately, I'm pretty sure that
forest = new Transform[10][10];
will not work.
But this should :
var forest : List.< Transform[] > = new List.< Transform[]>();
for (var i : int = 0; i < 10; i++)
{
var treeA : Transform[] = new Transform[10];
forest.Add (treeA);
}
update : didn't get what you were trying to do on first read, you can just make it a proper 2-dimensional array, like this:
var forest : Transform [,];
forest = new Transform [10,10];
Awesome! That was half the problem. Basically, I was declaring the array incorrectly (duh) and then I needed to do the casting thing as well when I instantiated.
Answer by 13dnizinski · Dec 17, 2013 at 05:22 AM
I ran into a similar problem myself. Here's how I solved it:
I used Resources.Load("Directory To Prefab"). In case you don't know how Resources.Load() works, it returns the object in the 'Resources' folder so you can use it. If you don't have one, just go to Create --> New Folder, and name it 'Resources'. The parameter for this function is the directory (as a string) to the object when you are already 'inside' the Resources folder.
For example, if I put a GameObject Thingy inside the Resources folder, I would get(return) it by saying:
Resources.Load("Thingy");
To use a new instance of that object that you have just returned, use
Instantiate(Resources.Load("Thingy")) as GameObject;
This will return an instance of the "Thingy" GameObject that you put in your Resources folder.
If you make a 'Resources' folder and put a 'Tree' object inside as type Transform, the key statement looks like so:
forest[i][j] = Instantiate(Resources.Load("Tree")) as Transform;