Search Unity

Unable To Add And Remove Gameobjects From Variant Prefabs Via Prefabutility

Discussion in 'Prefabs' started by thom66, Apr 12, 2019.

  1. thom66

    thom66

    Joined:
    Aug 14, 2017
    Posts:
    2
    Hi friends,

    I'm really struggling with finding a reliable way to edit prefabs through script, particularly variants.
    All I want to do is the equivalent of this:
    • Open a prefab variant in a scene
    • Open in edit mode
    • Add and delete some objects from it and set some values
    • Save
    I've tried InstantiatePrefab, LoadPrefabContents, Unpack, RecordModifications, ApplyOverrides, SaveAsPrefabAsset, they all end up either saving the variant as a new prefab instead of maintaining it's variant status, or not keeping the changes, or adding the object but not applying it so it constantly has the + next to it. I've tried the example shown here, but I don't want to add a component I want to delete and add game objects.
    I'd really love a decent walkthrough or tutorial on what the PrefabUtility class is actually doing. All the current tutorials are for using the Editor interface rather than scripting.

    My current attempt is this, but I have tried many others. This current incarnation doesn't change the object at all.

    Code (CSharp):
    1. string path = "path";
    2.         GameObject originalObject = Resources.Load( path ) as GameObject;
    3.  
    4.         string assetPath = "assetpath.prefab";
    5.  
    6.         GameObject newObject = PrefabUtility.LoadPrefabContents( assetPath );
    7.         PrefabUtility.UnpackPrefabInstance( newObject, PrefabUnpackMode.OutermostRoot, InteractionMode.AutomatedAction );
    8.  
    9.         PrefabUtility.RecordPrefabInstancePropertyModifications( newObject );
    10.  
    11.  
    12.         //Destroy any existing slots
    13.         for( int i = newObject.childCount - 1; i > -1; i-- )
    14.         {
    15.             Transform child = newObject.GetChild(i);
    16.  
    17.             DestroyImmediate( child.gameObject );
    18.         }
    19.  
    20.         //Add a slot for each slot in the original panel's data
    21.         for( int i = 0; i < origObj.NumChildren; i++ )
    22.         {
    23.             int numberOfSlots = i + 1;
    24.             GameObject newGm = new GameObject( "Slot" + numberOfSlots.ToString( "d2" ) );
    25.  
    26.             newGm.transform.parent = parent;
    27.  
    28.             newGm.transform.localPosition    = origObj.GetChild( i ).localPosition;
    29.             newGm.transform.localRotation    = origObj.GetChild( i ).localRotation;
    30.             newGm.transform.localScale        = origObj.GetChild( i ).localScale;
    31.  
    32.             Object slot = newGm.AddComponent<Object>();
    33.  
    34.         }
    35.  
    36.         PrefabUtility.ApplyObjectOverride( newObject, assetPath, InteractionMode.AutomatedAction );
    37.         PrefabUtility.UnloadPrefabContents( newObject );
    Any help on how to do the procedure in the bullet points above would be greatly appreciated!
    I really like the new prefab process, but the PrefabUtility API is baffling
     
  2. SteenLund

    SteenLund

    Unity Technologies

    Joined:
    Jan 20, 2011
    Posts:
    639
    Hi @thom66

    When modifying a variant like this there is 1 rule.
    Don't unpack the Variant, this will turn it into a regular prefab.

    Of course this means you won't be able to destroy GameObjects in variants only Components.
     
    Last edited: Apr 23, 2019
  3. thom66

    thom66

    Joined:
    Aug 14, 2017
    Posts:
    2
    Thank you!

    Looks like we'll need a new approach.

    Thom