- Home /
Best way to instantiate a prefab and store values with it?
I'm trying to make a scene with a set of objects created from prefabs. Each needs to have an x/y coord saved with it - not the actual transform position, but game coords used for procedurally generating their contents.
I have a 'SpawnSectors' script in my GameController object. In the start function I loop through instantiating the prefab, retrieving a script from the new object and call SetCoords. The SetCoords funtion just stores the values in private class members.
for (int x = -5; x < 5; x++)
{
for (int y = -5; y < 5; y++)
{
Vector3 pos = new Vector3(sectorSpawnOrigin.position.x + (x*100), sectorSpawnOrigin.position.y + (y*100), sectorSpawnOrigin.position.z);
GameObject sector = Instantiate(sectorPrefab, pos, sectorSpawnOrigin.rotation);
sector.transform.parent = sectorCanvasTransform;
PerlinToImageColour p2c = sector.GetComponent<PerlinToImageColour>();
p2c.SetCoords(x, y);
}
}
I notice from some debugging that all this happens before the new objects start function runs. It's in start that it uses the coords, however when this happens the coords have been reset to 0.
Does whatever calls the start function intentionally reset all fields to zero? How can I pass a value to a newly created object?
I'm very new to Unity, so am I going about this all the wrong way?
Thanks
Thinking about it, could there be some even I can listen for - so a script creates a bunch of objects then is able to register for when they're all 'ready' for further calls?
All seems a bit messy, like I'm going about things backwards - maybe because i'm trying to put the intelligence in the prefab rather than the thing creating the prefab. That does seem the more unity way though.
Answer by fafase · Dec 04, 2017 at 05:06 PM
Create a script and attach it to the prefab:
public class DataContainer:MonoBehaviour
{
int a, b;
public void SetValues(int a, int b)
{
this.a = a;
this.b = b;
}
public int GetA(){ return this.a; }
public int GetB(){ return this.b; }
}
On creation, access and set the values:
GameObject obj = (GameObject)Instantiate(prefab);
obj.GetComponent<DataContainer>().SetValues(i, j);
Another solution is to use a dictionary to store the value:
public struct DataStruct
{
public int a = 0;
public int b = 0;
public DataStruct(int a, int b)
{
this.a= a; this.b = b;
}
}
Dictionary<GameObject,DataStruct>dict = new Dictionary<GameObject, DataStruct>();
then in the loop when creating the object:
dict.Add((GameObject)Instantiate(prefab), new DataStruct(i, j));
Thanks for the reply.
Unless I've missed something though, isn't the first solution the same as $$anonymous$$e?
Instantiate object, get script on new object, call set function.
The problem I'm having is that after I call the set function and sure the values as class members the start function is called and the members reset.
Then don't reset the fields in start? :) They can't just reset unless you specifically reset them yourself or not initialize them at all.
No I'm saying they're already reset by something when start is called. It's like whatever calls start first zeros the object.
I've done some googling and found at least one other person who sees the same thing. $$anonymous$$aybe I can make a simple project that shows it and share.