- Home /
How can I update my prefab via script without changing my objects' positions?
I have a script that I'm using to import custom file types and export them to a prefab, essentially a custom content pipeline. I am using `OnPostProcessAllAssets` to import my file, and then converting the data into a prefab like so:
GameObject converted = new GameObject(); // Temp gameobject that will be converted into a prefab
// Omitted: Loading data and setting up gameobject components
UnityEngine.Object prefab = null;
prefab = AssetDatabase.LoadAssetAtPath(outputPath+".prefab", typeof(UnityEngine.Object));
if (prefab == null)
{
prefab = PrefabUtility.CreateEmptyPrefab(outputPath+".prefab");
}
PrefabUtility.ReplacePrefab(converted, prefab);
GameObject.DestroyImmediate(converted); // Clean up
However, when my prefab is updated this way, the instances of the object that are already in the scene get their positions changed to (0,0,0).
How can I update my prefab and its instances without changing their individual attributes like their positions?
Answer by phort99 · Feb 11, 2014 at 07:39 AM
From http://docs.unity3d.com/Documentation/ScriptReference/ReplacePrefabOptions.Default.html
If the game object hierarchy was not connected to the prefab before all game objects / components will be new and thus overrides in prefab instances will be lost.
This means if you just create a new gameobject and replace the old one in the prefab, the overrides (like position overrides and component values) will be lost. The solution was to load my prefab as a gameobject and modify that gameobject, thus preserving the connections.
Updated code:
GameObject prefab = null;
prefab = (GameObject)AssetDatabase.LoadAssetAtPath(outputPath+".prefab", typeof(GameObject));
if (prefab == null)
{
prefab = new GameObject();
PrefabUtility.CreatePrefab(outputPath+".prefab",instance);
}
// Now any changes made to the prefab object will be reflected in the prefab asset and in any instances in the scene.
prefab.name = Path.GetFileNameWithoutExtension(asset);
ExampleComponent c = instance.GetComponent<ExampleComponent>();
if (c == null)
{
c = prefab.AddComponent<ExampleComponent>();
}