Search Unity

All references to prefab lost after using PrefabUtility.SaveAsPrefabAsset(...) due to new FileId

Discussion in 'Prefabs' started by Manuel_H, Feb 21, 2019.

  1. Manuel_H

    Manuel_H

    Joined:
    Aug 3, 2017
    Posts:
    13
    I'm trying to manipulate a prefab via script in ways not supported by the new prefab system (like destroying a child, or reordering children). Before 2018.3, this could be achieved like this:

    Code (CSharp):
    1. var instance =(GameObject)PrefabUtility.InstantiatePrefab(SomePrefab);
    2. PrefabUtility.DisconnectPrefabInstance(instance);
    3. //Manipulations here
    4. PrefabUtility.ReplacePrefab(instance, SomePrefab);
    5. DestroyImmediate(instance);
    With the new system, the closest I could get to was this:

    Code (CSharp):
    1. var instance =(GameObject)PrefabUtility.InstantiatePrefab(SomePrefab);
    2. PrefabUtility.UnpackPrefabInstance(instance , PrefabUnpackMode.Completely, InteractionMode.AutomatedAction);
    3. //Manipulations here
    4. PrefabUtility.SaveAsPrefabAsset(instance , AssetDatabase.GetAssetPath(SomePrefab));
    5. DestroyImmediate(instance );
    However, with this new method the prefab file is assigned a new FileId and all references to it in scenes or other prefabs are lost. Using the deprecated ReplacePrefab instead of SaveAsPrefabAsset yields the exact same results. I have found that without unpacking the prefab all references stay intact after saving, but I need to unpack or else the manipulations will throw errors.

    Is this intended behavior? Or is there another way I can achieve this that I've missed? Thanks in advance.
     
  2. Manuel_H

    Manuel_H

    Joined:
    Aug 3, 2017
    Posts:
    13
    I missed
    ReplacePrefabOptions.ReplaceNameBased
    , using that it works as I want it to. This can be closed.
     
  3. SteenLund

    SteenLund

    Unity Technologies

    Joined:
    Jan 20, 2011
    Posts:
    639
    Yes this is intended behaviour, though we are considering improving it.

    The correct way for you would be to use PrefabUtility.LoadContents.
    Code (CSharp):
    1. var path = AssetDatabase.GetAssetPath(SomePrefab);
    2. var contentRoot = PrefabUtility.LoadPrefabContents(path);
    3. //Manipulations here
    4. PrefabUtility.SaveAsPrefabAsset(contentRoot , path);
    5. PrefabUtility.UnloadPrefabContents(contentRoot);
     
    Manuel_H likes this.
  4. Manuel_H

    Manuel_H

    Joined:
    Aug 3, 2017
    Posts:
    13
    Thanks, I'll check that out!
     
  5. xiaofeihu

    xiaofeihu

    Joined:
    Oct 9, 2012
    Posts:
    1
    Hello SteenLund

    Now I'm using the new prefab system. When I use PrefabUtility.SaveAsPrefabAsset api to replace a prefab by a new Instantiate gameObject, all references to the prefab also lost.
    Before I use PrefabUtility.ReplacePrefab to do it, and use ReplacePrefabOptions.ReplaceNameBased, it works fine, but now it does not work.
    How can I to do it?
     
  6. tcjkant

    tcjkant

    Joined:
    Jan 12, 2019
    Posts:
    15
    I am still having problems restoring my workflow with this new prefab system.

    What I had working before was to make some manual modifications to a prefab instance, and then perform an automated set of actions that would further modify the prefab instance and then apply the changes to the root prefab. All references to the root prefab remained intact.

    Like the OP, I've found that calling UnpackPrefabInstance and SaveAsPrefabAsset breaks all references to the previous prefab asset. Unfortunately, calling LoadPrefabContents rather than UnpackPrefabInstance doesn't really make any sense for my use case, since I want to do further automated processing to changes I've already made manually to a prefab instance. Calling LoadPrefabContents returns a gameobject with none of the changes I've made already that I need to keep.

    Any ideas on how to fix?
     
  7. vTimePawel

    vTimePawel

    Joined:
    Aug 1, 2017
    Posts:
    32
    Sorry for necro, just ran into this issue and it's completely messing with the dev flow. Any solutions?