Search Unity

How to repack unpacked prefabs

Discussion in 'Prefabs' started by prisonerjohn, Jan 27, 2019.

  1. prisonerjohn

    prisonerjohn

    Joined:
    Jul 31, 2013
    Posts:
    28
    I'm trying to create a prefab variant hierarchy in code and I'm having a few issues reconnecting my root prefab back when I'm done.

    Here is the Prefab architecture I have:
    Code (CSharp):
    1. - XX_Parent
    2.   -- XX_Child_A
    3.   -- XX_Child_B
    where XX_Child_A and XX_Child_B are nested prefabs inside of the XX_Parent prefab.

    And the result I would like is:
    Code (CSharp):
    1. - 00_Parent (Variant of XX_Parent)
    2.   -- 00_Child_A (Variant of XX_Child_A)
    3.   -- 00_Child_B (Variant of XX_Child_B)
    I followed this post to get to where I'm at, where they suggest to unpack the parent prefab in order to be able to edit and save variants of the child prefabs: https://forum.unity.com/threads/solved-creating-prefab-variant-with-script.546358/

    My issue is that I now cannot save back the parent as a variant of the original parent Prefab, as it seems the unpacking loses that connection.

    My code is something along the lines of the following. You can see at the bottom everything I've tried.

    The child prefabs I am saving are correctly set as variants of the original, but the parent prefab is its own independent thing.

    Any ideas how this can be achieved? Thank you!

    Code (CSharp):
    1.  
    2. // Build the parent.
    3. var parentObj = (GameObject)PrefabUtility.InstantiatePrefab(_parentPrefab);
    4. parentObj.name = "Parent";
    5.  
    6. // Build the prefab variant before unpacking, or else we'll lose the connection.
    7. var parentPrefabPath = _outputFolder + "/" + parentObj.name + ".prefab";
    8. var parentPrefab = PrefabUtility.SaveAsPrefabAsset(parentObj, parentPrefabPath);
    9.  
    10. // Unpack the prefab to modify its contents.
    11. PrefabUtility.UnpackPrefabInstance(parentObj, PrefabUnpackMode.OutermostRoot, InteractionMode.UserAction);
    12.  
    13. var outputChildPath = _outputFolder + "/" + parentObj.name + "_Clips";
    14. Directory.CreateDirectory(outputChildPath);
    15.  
    16. for (int i = 0; i < 2; ++i)
    17. {
    18.     // Find the corresponding clip prefab by name.
    19.     var childName = "Child_" + i;
    20.     Transform childTransform = parentObj.transform.Find(childName);
    21.  
    22.     // XXXXXX DO STUFF TO childTransform XXXXXX
    23.  
    24.     // Save child Prefab.
    25.     var childPrefabPath = outputChildPath + "/" + parentObj.name + "_" + childName + ".prefab";
    26.     //GameObject obj = PrefabUtility.SaveAsPrefabAsset(objSource, variantAssetPath);
    27.     PrefabUtility.SaveAsPrefabAssetAndConnect(childTransform.gameObject, childPrefabPath, InteractionMode.UserAction);
    28. }
    29.  
    30. // Save parent Prefab.
    31. //var parentPrefabPath = _outputFolder + "/" + parentObj.name + ".prefab";
    32. //PrefabUtility.SaveAsPrefabAssetAndConnect(parentObj, parentPrefabPath, InteractionMode.UserAction);
    33. //PrefabUtility.ApplyPrefabInstance(parentObj, InteractionMode.UserAction);
    34. PrefabUtility.ReplacePrefab(parentObj, parentPrefab, ReplacePrefabOptions.ConnectToPrefab);
     
  2. SteenLund

    SteenLund

    Unity Technologies

    Joined:
    Jan 20, 2011
    Posts:
    639
    What you are trying to achieve it not possible.

    A Variant can't destroy objects from its base, it can only add or modify.

    If you want to have the children use variants you need two different parent prefabs

    Code (CSharp):
    1. - XX_Parent
    2.     -- XX_Child_A
    3.     -- XX_Child_B
    4.  
    5. - YY_Parent
    6.     -- 00_Child_A (variant of XX_Child_A)
    7.     -- 00_Child_B (variant of XX_Child_B)
    8.  
     
  3. prisonerjohn

    prisonerjohn

    Joined:
    Jul 31, 2013
    Posts:
    28
    Ok, thanks for the answer. I ended up just having independent prefabs and combining them into one:
    Code (csharp):
    1. - XX_Parent
    2. - XX_Child_A
    3. - XX_Child_B
    Which becomes:
    Code (csharp):
    1. - YY_Parent (variant of XX_Parent)
    2.   -- YY_Child_A (variant of XX_Child_A)
    3.   -- YY_Child_B (variant of XX_Child_B)
    This seems to be working correctly, but I now would like to edit some parameters inside YY_Child_A and YY_Child_B and save those changes. I cannot figure out how to do this.

    Code (CSharp):
    1.  
    2. // Instantiate the parent.
    3. var parentObj = (GameObject)PrefabUtility.InstantiatePrefab(_parentPrefab);
    4.  
    5. for (int i = 0; i < 2; ++i)
    6. {
    7.     // Find the corresponding clip prefab by name.
    8.     var childName = "Child_" + i;
    9.     Transform childTransform = parentObj.transform.Find(childName);
    10.  
    11.     // XXXXXX DO STUFF TO childTransform XXXXXX
    12.  
    13.     // Save changes to child Prefab.
    14.  
    15.     // DOES NOT WORK, SAVES PARENT INSTEAD.
    16.     PrefabUtility.ApplyPrefabInstance(childTransform.gameObject, InteractionMode.UserAction);
    17.  
    18.     // DOES NOT WORK, DOESN'T SEEM TO DO ANYTHING...
    19.     var childPrefabPath = "whatever.prefab"
    20.     PrefabUtility.ApplyObjectOverride(childTransform.gameObject, childPrefabPath, InteractionMode.UserAction);    
    21. }
    Thanks