What factors affect a prefab's scale when instantiated?

I’m stumped!

I have one instance of a prefab placed in the scene (by hand in the editor), with a script (built into the prefab) that makes it stretch taller by simply adding a fixed amount to its scale each Update.

Then after a moment, I instantiate a second instance of the same prefab. (It has NO parent.)

Here’s the problem: The new instance spawns with the stretched-out scale that the first one has attained, rather than the prefab’s own native starting size which is much smaller.

Since parenting is ruled out (I explicity set it to null to be sure), what else could possibly affect an instance’s scale at the moment it appears? How could one instance be connected to the scale of the earlier instance? (Note: once created, I can scale it independently of the other. It’s just the creation scale that’s wrong, not a permanent connection.)

The prefab is the ONLY thing in the scene (except for a light and cam) and is constructed as follows:

  • A model with one script attached to make it grow.

  • A second model as a child of that, with a script that contains only a single function: one that causes a new instance to spawn when the first script calls on it. (Why 2 scripts instead of one? For future reasons I will need.)

  • What gets instantiated, of course, is another copy of the same prefab, with the same two models and same two scripts. So the process repeats, creating a third instance, a fourth, etc. (One every 2 seconds.) All share the same problem: they start at the final size of the last one instead of starting over small again. (I put them all at the origin to keep things simple.)

Here’s the child model’s script (“WeedBud2”) that spawns a new prefab instance when called (and this works fine):

var stem : GameObject;

function Branch () {
	var instantiated : GameObject = Instantiate (stem, Vector3.zero, Quaternion.identity);
	instantiated.transform.parent = null;
}

And here’s the parent model’s script that makes any given instance grow taller over time (which also works fine) and then calls on the function above:

private var childbud : WeedBud2;
childbud = gameObject.GetComponentInChildren(WeedBud2);

function Start () {
	StartCoroutine("GrowthDone");
}

function Update () {
	transform.localScale.y = transform.localScale.y + .5*Time.deltaTime; //Grow taller
}

function GrowthDone () {
	yield WaitForSeconds (2); //Grow for 2 seconds only, then Branch spawns new prefab
	childbud.Branch ();
	Destroy (this);
}

That’s it… no other scripting in the scene. What should I be looking for to explain why the second one spawns at the size of the first?

Note: I can be sure the prefab is not simply set to a large native size: I can vary size the first instance reaches (by changing the growth time), and the second one always matches. (And then grows from there–so each instance ends up bigger than the last.)

Thanks for any thoughts.

EDIT: I’ve stripped the project down to bare bones (new code pasted above) and it’s still happening :?

Ooooh plants that grow recursively. Very sweet! (Also explains your lightweight single child questions :slight_smile: )

What are all these things named?

You may be creating an instance of an object in the scene rather than of the prefab.

i’d guess it’s because you have your grow script on the prefab you’re instancing. when the game plays, it grows. so it’s been scaled when the 2nd instance is instantiated. set it up so the script is on an empty.

[edit: i guess that’s what podp was saying!]

Yep–recursive plants. And the weird thing is, this worked just fine in a rough test script, but that lacked the needed flexibility. “Weed Stem 2” is the parent being spawned, to which is attached “Weed Bud 2” that spawns another.

So… just have one empty GO controller script that all the prefabs call on when they want to spawn a new instance? That should be doable… I need the new instance to be parented to the calling instance (ultimately–not seen in this simple text) but I think I can get the calling instance to pass its own transform to the function being called.

I’ll be interested to see just how big my evil plant enemies can grow before bogging down the machine. Growth will be exponential (up to a point).

OK, that makes no difference… the same thing happens in the same way!

I now have an empty GameObject “Game Controller” with a universal “spawn script” called ThisBudsForYou:

function Spawn ( spawnchild, spawnparent, spawnpos, spawnrot ) {
	var instantiated : GameObject = Instantiate (spawnchild, spawnpos, spawnrot);
	instantiated.transform.parent = spawnparent;
}

And that gets called as follows–this “Branch” function replaces what I used above:

var stem : GameObject;

private var gamecontroller : ThisBudsForYou;
gamecontroller = GameObject.Find("Game Controller").GetComponent(ThisBudsForYou);

function Branch () {
	gamecontroller.Spawn ( stem, null, Vector3.zero, Quaternion.identity );
}

(The null means no parent.)

How can the spawned instance be inheriting scale from seemingly unrelated instances?

OK, here’s a clue I think:

When I assigned “stem” (the GO to be spawed), I did so in the prefab (the child of the pair), and I did it by dragging the prefab (the parent) onto the Inspector. Dragging FROM the Project list to an object IN the Project list. Not touching the instances already in my scene.

Yet when I click on the one in my scene, and check where “stem” traces back to, it connects to the instance in the SCENE, not the prefab in the project list.

I re-did the connection. It still won’t stick. I cannot make the script connect to the actual prefab instead of the instance. How do I fix this?

EDIT: I assume the problem stems (no pun intended) from the fact that one prefab is a child of the other. When I drag the pair to the scene, the link in the child to the parent becomes a link to the INSTANCED parent. I want the link to stay pointed at the SOURCE of the parent. How can this be done?

(Note: I can MANUALLY re-assign the link back to the prefab source, for the one that’s in the scene from the start. That fixes that one! But the next one that spawns has the same problem again.)

TIA

I think I’ve got a workaround! It seems like an ugly hack, so other suggestions are welcome, but I think I’m functional now :slight_smile:

I’m still using an empty GO (now called Spawner with a script of the same name) to do the instantiation, only now instead of passing the desired GO to Spawner, I’m now passing just an index to an array:

private var gamecontroller : ThisBudsForYou;
private var spawner : Spawner;
spawner = GameObject.Find("Spawner").GetComponent(Spawner);

function Branch () {
	spawner.Spawn ( 0, transform, transform.position, transform.rotation );
}

The 0 tells Spawner which object to spawn (I just drag the desired GO to slot 0):

var spawnitems : GameObject[];

function Spawn ( spawnchild, spawnparent, spawnpos, spawnrot ) {
	var instantiated : GameObject = Instantiate (spawnitems[spawnchild], spawnpos, spawnrot);
	instantiated.transform.parent = spawnparent;
}

Managing that array could get annoying as I add more and more items to the game, but it does seem to work!

Another option: StarManta just suggested Resources.Load, which I’m about to try. That sounds more streamlined!

I didn’t even know you could HAVE a GO not linked to any Inspector and still have it show up in the build.

I’d really like to see the project folder, that shows the original issue, without any workarounds.

I think I still have a VERY sloppy try-lots-of-stuff version that shows this child behavior. But I think anyone can reproduce it now:

  1. Make a prefab with a child.

  2. Put a script on the child with a GO variable.

  3. Drag the parent onto the child’s variable in the Inspector.

  4. Drag the parent to the scene (the child will follow).

  5. Click the newly-placed child’s variable, and see where it traces: to the newly-placed parent, not to the source prefab parent.

It’s not a bug I don’t think, just behavior I wasn’t expecting. I didn’t know that variable assignments would re-assign to maintain the hierarchy like that when instanced in a scene.

(If you still want me to send it, should I use email or Bug Reporter?)