Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Unpack prefab before building AssetBundles then repack with Undo

Discussion in 'Prefabs' started by BHGAhuerta, Jun 19, 2019.

  1. BHGAhuerta

    BHGAhuerta

    Joined:
    Apr 4, 2018
    Posts:
    14
    The AssetBundle build process does not cleanly handle nested prefabs that live outside of an asset bundle so we'd like to unpack a prefab, build the asset bundle the prefab belongs to, then undo the unpack.

    Here's the code I've written to test this:
    Code (CSharp):
    1. string guid = Selection.assetGUIDs[0];
    2.         string assetPath = AssetDatabase.GUIDToAssetPath(guid);
    3.         // load the prefab
    4.         GameObject obj = AssetDatabase.LoadAssetAtPath(assetPath, typeof(GameObject)) as GameObject;
    5.         if (obj == null)
    6.         {
    7.             throw new Exception("Could not load the prefab at " + assetPath);
    8.         }
    9.  
    10.         //Load up the prefab instance
    11.         GameObject prefabInstance = (GameObject)PrefabUtility.InstantiatePrefab(obj);
    12.         //register the undo
    13.         Undo.RecordObject(prefabInstance, "Undo unpack");
    14.         //Unpack
    15.         PrefabUtility.UnpackPrefabInstance(prefabInstance, PrefabUnpackMode.Completely, InteractionMode.UserAction);
    16.         bool success;
    17.         //Overwrite the prefab
    18.         PrefabUtility.SaveAsPrefabAsset(prefabInstance, assetPath, out success);
    19.         if (!success)
    20.         {
    21.             throw new Exception("oops");
    22.         }
    23.  
    24.         //Would build bundles here
    25.  
    26.         //repack the prefab
    27.         Undo.PerformUndo();
    28.         //Overwrite the prefab with what should be the original state
    29.         PrefabUtility.SaveAsPrefabAsset(prefabInstance, assetPath, out success);
    30.         if (!success)
    31.         {
    32.             throw new Exception("oops");
    33.         }
    From my testing the undo does not take place. I've also attempted using Undo.RegisterCompleteObjectUndo to no avail. It seems like the Overwriting clears the undo stack?

    Any Ideas?
     
  2. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,106
    Before build make any modifiations you need.
    Make build.
    After build just revert all modification through source control system you use :)
     
  3. BHGAhuerta

    BHGAhuerta

    Joined:
    Apr 4, 2018
    Posts:
    14
    Hey thanks for replying. I have considered that. It's not optimal because it requires the user to have a clean state before they build bundles. I can already imagine someone losing some work due to forgetting how the system works.
     
  4. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,106
    You right this will work only for build server where you always have clean state
    Or make another copy of working directory special for build system

    You can go further and store names of all changed prefabs...
    But I dont suggest to do so complicated build system :)
     
  5. BHGAhuerta

    BHGAhuerta

    Joined:
    Apr 4, 2018
    Posts:
    14
    We ended up going with creating a backup of the prefab in a different location and then moving it back after we build our bundles. This seems to work flawlessly without modifying the meta files.