- Home /
Child of prefab with local scene variables lose said data when parent prefab is edited?
Hello and thanks for your time.
Sorry if the title is a little vague. My issue is that I have created enemy prefabs with scripted points to travel between. The points are defined in script like:
var targetPoint : GameObject[];
Then in each scene the individual enemies have the points assigned in the editor via drag and drop.
Everything works fine except sometimes when I change anything in the prefab parent, like, say, move-speed, hitpoints, or physical mass, some (yes, weird bug) of the children of the prefab that populate the rest of my scenes that have had targetPoints assigned, lose them and I start getting lots of "UnassignedReferenceException:" errors.
Any ideas please? This makes me very leery of tuning anything at the prefab parent level, but that isn't a limitation I can live with.
Just checking: Which version of Unity are you using? As mentioned in my answer, I've seen this in earlier versions of Unity (not sure if I've still seen it in 2.6 but probably I did).
Answer by jashan · Aug 20, 2010 at 02:46 PM
I think I've seen the same behavior and agree that it's a problem. As far as I can tell, the issue arises from scene objects being dragged onto prefabs. You can drag project assets onto prefabs and it works smoothly, including dragging those prefabs into scenes and having everything "as designed". But when you drag objects from the scenes onto the prefabs (which there are obviously quite a few use cases for), the behavior you experienced seems to sometimes occur.
I'll just test if I can reproduce this in Unity 3 beta 5 ... and if so, will file a bug report. I'll also post a comment to your question with a question ;-)
EDIT: Ok, I did some extensive testing in the current Unity 3 beta and wasn't able to reproduce this issue. So, either it has been fixed somewhere along the way - or I'll need some more detailed steps of what you're doing. So here's what I did, and what works without any problem:
Created a little script for testing which should do what you are doing (more or less):
using UnityEngine; using System.Collections; using System.Collections.Generic;
public class SlotScript : MonoBehaviour { private static readonly JCsLogger log = new JCsLogger(typeof(SlotScript));
public int myInt;
public float myFloat;
public Transform transformX;
public Transform[] transformArray;
public List<Transform> tranformList;
public string mySeparator;
public GameObject gameObjectX;
public GameObject[] gameObjectArray;
public List<GameObject> gameObjectList;
}
Attached this to a game object and created a prefab from it.
Pulled a whole bunch of scene objects (from the hierarchy) on the slots (I had 5 slots for each list/array). I also added some random project objects (as this is a test-project, I simply used my prefab itself).
Applied the prefab. Obviously, it can't store the references to the scene objects to the prefab, so those remain null in the prefab.
Now, I "messed around" quite a bit: Created another instance of the prefab, changed everything, applied. Changed the prefab itself. Even changed the number of slots for my lists and arrays. Even added some extra public member variables to my class; some in-between the lists. Changed those values, too. Applied; changed in the prefab itself.
Also, I created another scene in which I applied similar changes (to see if this happens when a scene is currently not loaded).
My prefab with the scene objects still is exactly the same as it was.
So ... unless you're using some fancy editor scripting or have something weird in your project, this problem shouldn't occur for you in Unity 3.
Oh, one final note: Sometimes people stay in play mode and don't notice it. When you're in play, any changes you apply to prefabs actually remain, while any changes you apply to scene objects get lost as soon as you stop playing. It may be unlikely but I thought I should mention that this could be the problem ;-)
"Obviously, it can't store the references to the scene objects to the prefab, so those remain null in the prefab." - Which is what I think his problem is
Thank you for your efforts Jashan, much appreciated. I'm in a weird place where I don't really have time to do extensive testing (...$$anonymous$$ust...ship...Game!..) but if this keeps happening I may lose much more time having to go back and re-assign all of my enemies paths. Doh!!! I'll revisit it though before the bounty expires and make sure it doesn't pass unrewarded. Playmode edits vs Not playmode edits yeah, I'm very careful of it. Somethings stick and some don't. I haven't tried to pin down which do and don't and just treat Playmode edits as BAD JUJU, and not to be trusted. :)
Thanks again for verifying that it's an issue and not happening in U3. Now if someone will donate cough the cost to upgrade to U3 my issue will stop. :( I guess I'll try to restore levels from backup copies and hope that doesn't mess with things to much and or lose to much work.
If you're using Unity Pro, the upgrade is currently discounted ($500) ... might be worth getting that before it returns to the regular price ($750) once Unity 3 is released (which I think won't take that long). If you're using Unity ("free"), there wouldn't be an update price at all because it's free ;-)
Answer by spinaljack · Aug 17, 2010 at 10:37 AM
Prefabs don't save object instances. e.g. You can set variables like health and it'll be saved in the prefab but if you wanted to save a reference to an object in the scene (like a walk path or player location) then it wont actually be saved.
The reason for this is that prefabs need to be independent of the scene so that you can instantiate copies in any scene. Scene specific references wouldn't exist in a different scene so it's not stored.
If you make regular changes to your prefabs it's best to use a script to find your scene objects during run time with GameObject.Find or FindWithTag so save you having to check every prefab after any change.
No offence but I think you are wrong. Why else would there be prefabs if you couldn't set local variables in the children of the prefabs?
Here's a simple test, create an empty scene with a cube in it. Write a script that assigns another cube in the scene as a variable (var other : GameObject;) and then save it to a prefab. $$anonymous$$ake a new scene and load the prefab, there wont be anything in the reference variable because prefabs don't work the way you imagine.
Bounty added. I have scripted variables on my enemies that are set locally. Sometimes, with increasing frequency, if I make changes to the prefab the enemies are children of they are losing thier scene specific data. I don't think that each enemy needs it's own script as that invalidates the use of a prefab in the first place.
Why do you have enemies as children of another object anyway? If you want to pass information to them you can do that without using transform
From what I can read here, it's not the enemies that are children but the enemies have an array of waypoints from the scene. And of course, there are use cases where you put the enemies as children of another object: First thing that comes to $$anonymous$$d is for scene organization purposes where you might want to have all enemies under one "Enemies" parent game object. Another use case is when the enemies are attached to some sort of platform that moves around which would have to be the parent of the enemies for the most straightforward implementation of the animation.
Your answer
Follow this Question
Related Questions
Instantiate prefab with different variables 0 Answers
When I instantiate a prefab, I want to assign it custom values. 1 Answer
How to instantiate an object with scripts? 1 Answer
How do I access variables of prefabs I am loading via Resource.LoadAll, in script(C#) 2 Answers
Is it safe to save values in a prefab instead of using PlayerPrefs? 0 Answers