weird prefab behavior

I am trying to spawn some particle effects in run-time, and vary the colors. The problem is that the effects (which are prefabs) seem to have a shared particle animator, so when I grab the colorAnimation property of one to change it, it changes in all of them.

I thought I might be able to get around this by removing the ParticleAnimator component from my prefab and adding it manually in run-time.

Not only does this have the same effect, but my prefab gets the component added-- and it retains it even after the game quits back to the editor. This is a little unsettling, since I wasn’t aware that changes to objects in a scene could affect prefabs…

Is that a bug? What is a good approach for changing the colors on otherwise identical particle effects? It looks like I can’t just build them from scratch because they’ll “stick” to my prefabs…

thanks…

If you don’t instantiate the object at runtime (I assume you’re using Resources.load to get the particle system), then components added to the prefab get stored on the prefab.

Eg.

var pSystem : GameObject = Resources.Load("ParticleSystem1");
pSystem.AddComponent(ParticleAnimator);

This will add the ParticleAnimator component to the actual prefab. If you want the prefab to remain the same, and only add the component to the runtime object you need to make a copy of the prefab like so.

var pSystem : GameObject = Instantiate(Resources.Load("ParticleSystem1"));
pSystem.AddComponent(ParticleAnimator);

That will create a copy in the runtime scene and only alter the copy.
Make sure that the path you’re using for Resources.Load there is valid though, as it will cause a null reference exception if it isn’t.

Please show your code so we can help look at this. That’s definitely not the expected behavior so I’m wondering what your code looks like and if you’re somehow thinking you’re adding the component to the instance but in reality are adding it to the prefab reference instead.

Here’s what I have:

var effect : GameObject;

function SetColor(c : Color)
{
	effect.gameObject.AddComponent("ParticleAnimator");
	var p = effect.gameObject.GetComponent("ParticleAnimator");
	var colors = p.colorAnimation;
	for(var k = 0; k < 5; k++)
	{
		colors[k]=Color(c.r,c.g,c.b,(4.0-k)/5.0);
	}
	p.colorAnimation=colors;
}

…where effect is a prefab made of an empty game object with a particle emitter and renderer attached (but no particle animator). I call it 3 times on 3 different objects, each with a different color, but they all end up with whatever the last color was. After that, when I stop the game and return to the editor, the prefab has the animator added as a component.

If you want I can create a mini-project with an example and send it your way, Tom.

By your own code you are modifying the prefab whereas it seems that you want to modify instances of the prefab (the last edit on the prefab “wins” and will propagate out to all instances using that prefab). Feel free to add the component to the prefab as all instances will need it (just be sure you only add it to the prefab once, not repetitively), but make sure that you set the colors and whatnot on the instances so they’re unique from each other.

Sorry, here’s the more complete code:

var effect : GameObject;

function Start()
{
	if(effect)
	{
		effect = GameObject.Instantiate(effect,transform.position,transform.rotation);
		effect.transform.parent=transform;
	}
}

function SetColor(c : Color)
{
	var p = effect.gameObject.GetComponent("ParticleAnimator");
	var colors = p.colorAnimation;
	for(var k = 0; k < 5; k++)
	{
		colors[k]=Color(c.r,c.g,c.b,Mathf.Sqrt((5.0-k)/5.0));
	}
	p.colorAnimation=colors;
}

This exhibits the same problem… (another objects calls SetColor() on it later)

You declare ‘effect’, and I assume drag-assign the prefab as the value. Then you instantiate the prefab re-using that same variable as the result. This is bound to cause confusion and may be the source of problems here. Use separate variables, one that refers to the source prefab and one that refers to the instanced copy of it, then work with the instanced copy not the source.

And your code still isn’t complete as it’s not clear how/when you call SetColor. :slight_smile: