- Home /
Apply prefab change though script without loosing reference
Hey, I've been stuck for a while now. My problem is that i want to apply changes to a prefab made though an editor script, but whenever i do so(though misc methods), it either breaks the prefab reference, or Unity reverts it when its closed. So, i am wondering, is there any way to do something like PrefabUtility.ApplyChanges() or similar?
I have seen other posts where they suggest PrefabUtility.Replace(), but it makes no sense for me. First of all it breaks connection, secondly it actually requires an object. I am loading the prefab i want though Assetdatabase, because PrefabUtility.Instantiate() requires an object, which i don't have, as the class is static.
It is quite mindblowing for me that its SOOOO hard to apply a prefab change through script...
PS: could anyone explain to my why Unity reverts prefab changes when you close Unity?
Answer by edwardrowe · Aug 31, 2016 at 04:08 PM
If you are changing the Prefab Asset in the Project you should just use EditorUtility.SetDirty(), I believe. Unity says it's going to be deprecated, but I think that's for scene objects. You can force the AssetDatabase to SaveAssets, if you don't want closing it to revert the changes. But it's kind of wrong to automatically save the user's assets for them, IMO.
If you are wanting to change an instance of a prefab and apply it to the prefab (like pressing the "Apply" button in the inspector), you should use PrefabUtility.ReplacePrefab() as you've heard. It shouldn't break the connection if you pass the ReplacePrefabOptions.ConnectToPrefab as the last parameter:
PrefabUtility.ReplacePrefab(prefabInstance, sourcePrefab, ReplacePrefabOptions.ConnectToPrefab);
Using PrefabUtility.ReplacePrefab(), the link to the GameObject is kept, but the links to the GameObject's $$anonymous$$onoBehaviours are broken. Using references to the GameObject ins$$anonymous$$d of my own $$anonymous$$onoBehaviour should technically work but that would make the whole code less simple, less readable, and with lower performance because of the many GetComponent that would require. Is there any way to keep the link on a particular $$anonymous$$onoBehaviour of the replaced prefab? Setting the fileID manually? (that seems to be the one ID that breaks the link)
I'm not sure I fully understand the issue you are having. I can't replicate those results. Here's what I'm doing:
I have a GameObject in a scene that's an instance of a prefab. It includes a $$anonymous$$onoBehaviour that has serialized references to some of its components. I make changes to that object. I can apply those changes to its prefab in script using the code:
PrefabUtility.ReplacePrefab(prefabInstance, sourcePrefab, ReplacePrefabOptions.ConnectToPrefab);
.
References to its components are maintained in the $$anonymous$$onoBehaviour.
$$anonymous$$aybe the difference is that your $$anonymous$$onobehaviour "has serialized references to some of its components". In my case, prefab A's $$anonymous$$onoBehaviour has reference to prefab B's component. If I ReplacePrefab prefab B, the reference is lost. But if prefab A's $$anonymous$$onoBehaviour has a reference to prefab B's root GameObject, there is no problem.
Your answer

Follow this Question
Related Questions
How do I change the name of the prefab in the prefab folder with code? 0 Answers
Should I be able to cast the result of PrefabUtility.GetPrefabObject() to a GameObject? 0 Answers
Execute code once when a prefab is placed into the scene? 2 Answers
cannot load GameObject Prefabs using Resources.Load in Android 0 Answers