Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Bulk prefab saving script has unexpected results

Discussion in 'Scripting' started by strich, Mar 9, 2015.

  1. strich

    strich

    Joined:
    Aug 14, 2012
    Posts:
    346
    I find myself doing a lot of prefab modifications in the scene and to save myself time of hitting the Apply button on prefabs all the time I've written a short script to bulk save all the prefabs I have selected:

    Code (CSharp):
    1. [MenuItem("Save selected prefabs")]
    2.     static void SaveSelectedPrefabs()
    3.     {
    4.         var prefabs = new List<GameObject>(Selection.gameObjects);
    5.  
    6.         foreach (var prefab in prefabs) {
    7.             var prefabMods = PrefabUtility.GetPropertyModifications(prefab);
    8.             var prefabParent = PrefabUtility.GetPrefabParent(prefab);
    9.             PrefabUtility.SetPropertyModifications(prefabParent, prefabMods);
    10.         }
    11.  
    12.         AssetDatabase.SaveAssets();
    13.         AssetDatabase.Refresh();
    14.  
    15.         Debug.Log(prefabs.Count + " prefabs saved.");
    16.     }
    This all appears to work - The prefabMods contains all the modifications and I can see the prefab file has been updated with the list of modifications. But the weird part here is that the prefab file has not got its actual data update but a 'modifications' list at the bottom of the file is populated:
    Code (text):
    1. Prefab:
    2.   m_ObjectHideFlags: 1
    3.   serializedVersion: 2
    4.   m_Modification:
    5.     m_TransformParent: {fileID: 0}
    6.     m_Modifications:
    7.     - target: {fileID: 400000}
    8.       propertyPath: m_LocalPosition.x
    9.       value: -11.3400002
    10.       objectReference: {fileID: 0}
    11.     - target: {fileID: 400000}
    12.       propertyPath: m_LocalPosition.y
    13.       value: 0
    14.       objectReference: {fileID: 0}
    15. etc...
    If I delete the in-scene prefabs and pull them back out again from the prefab assets, none of the modifications have stuck.

    Ideas?
     
  2. BubbaRichard

    BubbaRichard

    Joined:
    Jul 1, 2012
    Posts:
    51
    try this instead:
    (sorry for any typo's but tested the code on one computer and replying on a different one :) )
    foreach(GameObject gobj in Selection.gameObjects)
    {
    var original = Prefabutility.GetPrefabParent(gobj);
    PrefabUtility.replacePrefab(gobj, original);
    }
     
  3. Steven-Walker

    Steven-Walker

    Joined:
    Oct 27, 2010
    Posts:
    38
    For anyone looking for this solution for 2018:

    Code (CSharp):
    1.    
    2. // shortcut Shift+Ctrl+Alt+S
    3. [MenuItem("Tools/AxonGenesis/Utilities/Save Selected Prefabs %#&s", false, 153)]
    4. static public void SavePrefabs() {
    5.     foreach(GameObject obj in Selection.gameObjects) {
    6.         var original = PrefabUtility.GetCorrespondingObjectFromSource(obj);
    7.         PrefabUtility.ReplacePrefab(obj, original);
    8.     }
    9. }
    10.