Search Unity

Replace game object with prefab?

Discussion in 'Editor & General Support' started by DaveA, Jun 4, 2009.

  1. stdiopt

    stdiopt

    Joined:
    Feb 1, 2015
    Posts:
    3
    Does this script maintain the order in hierarchy?, Lets say in a RectTransform i want to replace all backgrounds with some prefab instance, I did something already but, the issue is when adding Prefab, it becomes last child keeping the background "rect transform" on top of every other elements (I guess hierarchy order matter in RectTransforms),

    Is there a easy way to replace a gameObject maintaining hierarchy order?
     
  2. VesuvianPrime

    VesuvianPrime

    Joined:
    Feb 26, 2013
    Posts:
    131
  3. noctvm

    noctvm

    Joined:
    Dec 19, 2015
    Posts:
    1
    Hi guys, I have a problem hen I drag the script, a windows said that I can't add the script because need to derivate from monobehaviour, do you know why?

    cheers.
     
  4. Carolinetis

    Carolinetis

    Joined:
    Feb 20, 2016
    Posts:
    11
    Hi everyone! I'm new using Unity and found your script very useful and necessary, but I have a question... where should I place it to use it? I know it's a very basic question, I'm sorry. I'd appreciate any help.

    Thanks again!
     
  5. Mark-Davis

    Mark-Davis

    Joined:
    Jun 21, 2011
    Posts:
    152
    Huge thanks to everyone who worked on this! I was able to replace these books in a few seconds. Awesome!
    MoreBooks.jpg
     
  6. Arno1975

    Arno1975

    Joined:
    Aug 14, 2013
    Posts:
    40
    I'm getting an error

     
  7. ethos42

    ethos42

    Joined:
    Dec 20, 2016
    Posts:
    1
    This did exactly what I needed for my situation. Thanks!
     
  8. muzboz

    muzboz

    Joined:
    Aug 8, 2012
    Posts:
    63
    FYI, for anyone just coming to this thread and looking for the best version, I found "fermmmm"s version the best that I tried.

    I tried "VesuvianPrime"'s but it wouldn't compile because it needed other "Hydra" code.

    So I went back further and tried "Elzean"'s version, but I kept mucking it up, and having swizzly problems with it, and having objects deleted.

    So I went back to "fermmmm"s nice simple one adn it worked first go, nice and straight forward!

    I didn't try any further back.

    Thanks all, very handy!
     
  9. kapyar

    kapyar

    Joined:
    Dec 13, 2014
    Posts:
    6
    My version of this script
    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEditor;
    3. using UnityEngine;
    4.  
    5. public class ReplaceGameObjects : ScriptableWizard
    6. {
    7.     [System.Serializable]
    8.     public class Rule
    9.     {
    10.         public string Key;
    11.         public GameObject Value;
    12.     }
    13.  
    14.     public bool IsDeleteOld;
    15.     public bool IsCreateNewRoot;
    16.  
    17.     [Tooltip("If no prefix will use New_<Root.name>")]
    18.     public string CustomPrefix;
    19.  
    20.     public GameObject Root;
    21.  
    22.     public List<Rule> toReplace;
    23.  
    24.     private List<GameObject> toDelete = new List<GameObject>();
    25.  
    26.     private const string PREFIX = "New_";
    27.  
    28.     [MenuItem("Area730/Replace GameObjects")]
    29.     static void CreateWizard()
    30.     {
    31.         Debug.Log("[ReplaceGameObjects] CreateWizard");
    32.         ScriptableWizard wiz = DisplayWizard("Replace GameObjects", typeof(ReplaceGameObjects), "Close", "Replace");
    33.     }
    34.  
    35.     void OnWizardCreate()
    36.     {
    37.  
    38.     }
    39.  
    40.     void OnWizardOtherButton()
    41.     {
    42.         Debug.Log("[ReplaceGameObjects] OnWizardCreate");
    43.  
    44.         if (string.IsNullOrEmpty(CustomPrefix))
    45.         {
    46.             CustomPrefix = PREFIX;
    47.         }
    48.  
    49.         ChangeInSelectedRoot();
    50.  
    51.         ShowNotification("Job is done");
    52.     }
    53.  
    54.     void OnWizardUpdate()
    55.     {
    56.         if (Root == null)
    57.         {
    58.             errorString = "Assign the root object!";
    59.             isValid = false;
    60.         }
    61.         else
    62.         {
    63.             errorString = "";
    64.             isValid = true;
    65.         }
    66.  
    67.         helpString = "Replace objects that has same NAME with one Prefab";
    68.     }
    69.  
    70.  
    71.     private void ChangeInSelectedRoot()
    72.     {
    73.         var goChild = Root.GetComponentInChildren<Transform>();
    74.  
    75.         GameObject currentRoot;
    76.         if (IsCreateNewRoot)
    77.         {
    78.             var newRoot = GameObject.Find(CustomPrefix + Root.name);
    79.  
    80.             if (newRoot == null)
    81.             {
    82.                 newRoot  = new GameObject(CustomPrefix + Root.name);
    83.  
    84.                 newRoot.transform.position = Root.transform.position;
    85.                 newRoot.transform.rotation = Root.transform.rotation;
    86. //                newRoot.transform.lossyScale = Root.transform.lossyScale;
    87.  
    88.                 newRoot.isStatic = Root.isStatic;
    89.             }
    90.             currentRoot = newRoot;
    91.         }
    92.         else
    93.         {
    94.             currentRoot = Root;
    95.         }
    96.  
    97.         if (goChild != null)
    98.         {
    99.             foreach (Transform child in goChild)
    100.             {
    101.                 foreach (var replace in toReplace)
    102.                 {
    103.                     string nameKey = replace.Key;
    104.  
    105.                     if (nameKey == child.name)
    106.                     {
    107.                         GameObject newObject;
    108.                         newObject = (GameObject) EditorUtility.InstantiatePrefab(replace.Value);
    109.  
    110.                         if (child.transform.parent.name == Root.name)
    111.                         {
    112.                             newObject.transform.parent = currentRoot.transform;
    113.                         }
    114.                         else
    115.                         {
    116.                             newObject.transform.parent = child.transform.parent;
    117.                         }
    118.  
    119.                         newObject.transform.localPosition = child.transform.localPosition;
    120.                         newObject.transform.localRotation = child.transform.localRotation;
    121.                         newObject.transform.localScale    = child.transform.localScale;
    122.  
    123. //                        Debug.Log(string.Format("[ReplaceGameObjects] {0} in {1}", child.transform.localPosition, newObject.transform.localPosition));
    124.                         toDelete.Add(child.gameObject);
    125.                     }
    126.                 }
    127.             }
    128.         }
    129.  
    130.         if (IsDeleteOld)
    131.         {
    132.             foreach (var del in toDelete)
    133.             {
    134.                 DestroyImmediate(del);
    135.             }
    136.         }
    137.     }
    138.  
    139.  
    140.     private void ShowNotification(string msg)
    141.     {
    142.         EditorUtility.DisplayDialog(msg, "", "Ok");
    143.     }
    144. }
    145.  
    146.  
     
  10. NSwat

    NSwat

    Joined:
    Apr 22, 2017
    Posts:
    6
    This is a amazing, must have script.
    thx
     
  11. _creatio_

    _creatio_

    Joined:
    Mar 21, 2013
    Posts:
    37
    Midfied @Elzean 's version to make it work with Unity 5.6.1 No other changes.
    Thank you guys for such a usefull tool!

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using System.Collections.Generic;
    4. // CopyComponents - by Michael L. Croswell for Colorado Game Coders, LLC
    5. // March 2010
    6. //Modified by Kristian Helle Jespersen
    7. //June 2011
    8. //Modified by Connor Cadellin McKee for Excamedia
    9. //April 2015
    10. //Modified by Fernando Medina (fermmmm)
    11. //April 2015
    12. //Modified by Julien Tonsuso (www.julientonsuso.com)
    13. //July 2015
    14. //Changed into editor window and added instant preview in scene view
    15. //Modified by Alex Dovgodko
    16. //June 2017
    17. //Made changes to make things work with Unity 5.6.1
    18. public class ReplaceWithPrefab : EditorWindow
    19. {
    20.     public GameObject Prefab;
    21.     public GameObject[] ObjectsToReplace;
    22.     public List<GameObject> TempObjects = new List<GameObject>();
    23.     public bool KeepOriginalNames = true;
    24.     public bool EditMode = false;
    25.     // Add menu named "My Window" to the Window menu
    26.     [MenuItem("Window/ReplaceWithPrefab")]
    27.     static void Init()
    28.     {
    29.         // Get existing open window or if none, make a new one:
    30.         ReplaceWithPrefab window = (ReplaceWithPrefab)EditorWindow.GetWindow(typeof(ReplaceWithPrefab));
    31.         window.Show();
    32.     }
    33.     void OnSelectionChange()
    34.     {
    35.         GetSelection();
    36.         Repaint();
    37.     }
    38.     void OnGUI()
    39.     {
    40.         EditMode = GUILayout.Toggle(EditMode, "Edit");
    41.         if (GUI.changed)
    42.         {
    43.             if(EditMode)
    44.                 GetSelection();
    45.             else
    46.                 ResetPreview();
    47.         }
    48.         KeepOriginalNames = GUILayout.Toggle(KeepOriginalNames, "Keep names");
    49.         GUILayout.Space(5);
    50.         if (EditMode)
    51.         {
    52.             ResetPreview();
    53.          
    54.             GUI.color = Color.yellow;
    55.             if (Prefab != null)
    56.             {
    57.                 GUILayout.Label("Prefab: ");
    58.                 GUILayout.Label(Prefab.name);
    59.             }else{
    60.                 GUILayout.Label("No prefab selected");
    61.             }
    62.             GUI.color = Color.white;
    63.          
    64.             GUILayout.Space(5);
    65.             GUILayout.BeginScrollView(new Vector2());
    66.             foreach (GameObject go in ObjectsToReplace)
    67.             {
    68.                 GUILayout.Label(go.name);
    69.                 if (Prefab != null)
    70.                 {
    71.                     GameObject newObject;
    72.                     newObject = (GameObject)PrefabUtility.InstantiatePrefab(Prefab);
    73.                     newObject.transform.SetParent(go.transform.parent, true);
    74.                     newObject.transform.localPosition = go.transform.localPosition;
    75.                     newObject.transform.localRotation = go.transform.localRotation;
    76.                     newObject.transform.localScale = go.transform.localScale;
    77.                     TempObjects.Add(newObject);
    78.                     if (KeepOriginalNames)
    79.                         newObject.transform.name = go.transform.name;
    80.                     go.SetActive(false);
    81.                 }
    82.             }
    83.             GUILayout.EndScrollView();
    84.             GUILayout.Space(5);
    85.             GUILayout.BeginHorizontal();
    86.             if(GUILayout.Button("Apply"))
    87.             {
    88.                 foreach (GameObject go in ObjectsToReplace)
    89.                 {
    90.                     DestroyImmediate(go);
    91.                 }
    92.                 EditMode = false;
    93.             };
    94.             if (GUILayout.Button("Cancel"))
    95.             {
    96.                 ResetPreview();
    97.                 EditMode = false;
    98.             };
    99.             GUILayout.EndHorizontal();
    100.         }
    101.         else
    102.         {
    103.             ObjectsToReplace = new GameObject[0];
    104.             TempObjects.Clear();
    105.             Prefab = null;
    106.         }
    107.      
    108.     }
    109.     void OnDestroy()
    110.     {
    111.         ResetPreview();
    112.     }
    113.     void GetSelection()
    114.     {
    115.         if (EditMode && Selection.activeGameObject != null)
    116.         {
    117.             PrefabType t = PrefabUtility.GetPrefabType(Selection.activeGameObject);
    118.             if (t == PrefabType.Prefab) //Here goes the fix
    119.             {
    120.                 Prefab = Selection.activeGameObject;
    121.             }
    122.             else
    123.             {
    124.                 ResetPreview();
    125.                 ObjectsToReplace = Selection.gameObjects;
    126.             }
    127.         }
    128.     }
    129.     void ResetPreview()
    130.     {
    131.         if (TempObjects != null)
    132.         {
    133.             foreach (GameObject go in TempObjects)
    134.             {
    135.                 DestroyImmediate(go);
    136.             }
    137.         }
    138.         foreach (GameObject go in ObjectsToReplace)
    139.         {
    140.             go.SetActive(true);
    141.         }
    142.         TempObjects.Clear();
    143.     }
    144. }
     
    nirvanajie and Elzean like this.
  12. seyacat

    seyacat

    Joined:
    Sep 10, 2015
    Posts:
    23
    Ty so much, you save my day, replace based on selection its the better choice.
    EDITED:
    I need to replace and save scene

    EditorApplication.MarkSceneDirty ();

    makes the magic.
     
    Last edited: Sep 28, 2017
  13. xelanoimis

    xelanoimis

    Joined:
    Oct 29, 2013
    Posts:
    30
    Thank you all for this. Time to share my version (no menu but shortcuts). It works like this:

    1. select some objects in scene view or scene hierarchy (hold ctrl key for multiple objects)
    2. select one prefab in project window or one more object in scene view
    3. Ctrl+Shift+R to replace all other objects with the last one (active selection)
    or
    Ctrl+Shift+D to clone the last one at each of selected objects positions (don't delete destinations)

    Works with normal instance (not prefab instance) as reference so it's easy to use it directly in the scene view to replace or duplicate objects.

    Also it supports undo and it keeps the nice order in the hierarchy.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using System.Collections.Generic;
    4. using UnityEditor.SceneManagement;
    5.  
    6. public class GFTools
    7. {
    8.     // hot keys: _ normal, # ctrl, % shift, & alt
    9.  
    10.     [MenuItem("Tools/GF/Duplicate with prefab #%D")]
    11.     private static void DuplicateWithPrefab()
    12.     {
    13.         InstantiateWithPrefab(false);
    14.     }
    15.  
    16.     [MenuItem("Tools/GF/Replace with prefab #%R")]
    17.     private static void ReplaceWithPrefab()
    18.     {
    19.         InstantiateWithPrefab(true);
    20.     }
    21.  
    22.     private static void InstantiateWithPrefab(bool deleteDestination)
    23.     {
    24.         GameObject originalObject = null;
    25.         Object[] prefabList = Selection.GetFiltered(typeof(UnityEngine.GameObject), SelectionMode.Assets);
    26.  
    27.         // try to find a prefab
    28.         foreach (var o in prefabList)
    29.         {
    30.             PrefabType t = PrefabUtility.GetPrefabType(o);
    31.             if (t == PrefabType.Prefab || t == PrefabType.ModelPrefab)
    32.             {
    33.                 if (originalObject == null)
    34.                 {
    35.                     originalObject = o as GameObject;
    36.                 }
    37.                 else
    38.                 {
    39.                     Debug.Log("select only one prefab in project window");
    40.                     return;
    41.                 }
    42.             }
    43.         }
    44.  
    45.         // if no prefab found, use active object
    46.         if (originalObject == null)
    47.         {
    48.             originalObject = Selection.activeGameObject;
    49.         }
    50.  
    51.         if (originalObject == null)
    52.         {
    53.             Debug.Log("select one prefab in project window or an object in the scene window");
    54.             return;
    55.         }
    56.  
    57.         // clear selection
    58.         Selection.objects = new Object[0];
    59.  
    60.         if (deleteDestination)
    61.             Debug.Log("Replacing with " + originalObject.name + ":");
    62.         else
    63.             Debug.Log("Duplicating " + originalObject.name + " at:");
    64.  
    65.         List<GameObject> newObjects = new List<GameObject>();
    66.  
    67.         for (int i=0; i<prefabList.Length; i++)
    68.         {
    69.             GameObject go = prefabList[i] as GameObject;
    70.             if (!go || go == originalObject)
    71.                 continue;
    72.  
    73.             PrefabType t = PrefabUtility.GetPrefabType(go);
    74.             if (t != PrefabType.Prefab && t != PrefabType.ModelPrefab)
    75.             {
    76.                 Debug.Log("  " + (newObjects.Count + 1).ToString() + " " + go.name);
    77.  
    78.                 GameObject newObject;
    79.  
    80.                 newObject = (GameObject)PrefabUtility.InstantiatePrefab(originalObject);
    81.                 if(newObject == null)
    82.                 {
    83.                     newObject = GameObject.Instantiate(originalObject);
    84.                     if (newObject == null)
    85.                     {
    86.                         Debug.Log("failed to instantiate");
    87.                         break;
    88.                     }
    89.                 }
    90.  
    91.                 Undo.RegisterCreatedObjectUndo(newObject, "created prefab");
    92.                 newObject.name = originalObject.name;
    93.  
    94.                 newObject.transform.SetParent(go.transform.parent, true);
    95.                 newObject.transform.localPosition = go.transform.localPosition;
    96.                 newObject.transform.localRotation = go.transform.localRotation;
    97.                 newObject.transform.localScale = go.transform.localScale;
    98.                 newObject.transform.SetSiblingIndex(go.transform.GetSiblingIndex()+1);
    99.  
    100.                 newObjects.Add(newObject);
    101.  
    102.                 if (deleteDestination)
    103.                     Undo.DestroyObjectImmediate(go);
    104.             }
    105.         }
    106.  
    107.         Selection.objects = newObjects.ToArray();
    108.  
    109.         EditorSceneManager.MarkAllScenesDirty();
    110.     }
    111. }
     
    leni8ec, ChaosWWW and ZiadJ like this.
  14. Macabana

    Macabana

    Joined:
    Oct 17, 2013
    Posts:
    3
    I really appreciate all that folk that have add a line in this incredible script that save hours of work, I can't believe how this handy tool is not part of Unity regular tools
     
  15. Feelnside

    Feelnside

    Joined:
    Sep 30, 2016
    Posts:
    58
    Thanks to everyone who was took a part in the script development. That script saved so much time of work!
     
  16. Hypertectonic

    Hypertectonic

    Joined:
    Dec 16, 2016
    Posts:
    27
    This is an update from @_creatio_ and @Elzean 's version, with an extra set of booleans to chose if scale and rotation should be applied to the prefab instances or ignored. Also added @seyacat 's suggestion.
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using UnityEditor.SceneManagement;
    4. using System.Collections.Generic;
    5.  
    6. // COMMUNITY THREAD LINK https://forum.unity.com/threads/replace-game-object-with-prefab.24311/
    7. // CopyComponents - by Michael L. Croswell for Colorado Game Coders, LLC
    8. // March 2010
    9. //Modified by Kristian Helle Jespersen
    10. //June 2011
    11. //Modified by Connor Cadellin McKee for Excamedia
    12. //April 2015
    13. //Modified by Fernando Medina (fermmmm)
    14. //April 2015
    15. //Modified by Julien Tonsuso (www.julientonsuso.com)
    16. //July 2015
    17. //Changed into editor window and added instant preview in scene view
    18. //Modified by Alex Dovgodko
    19. //June 2017
    20. //Made changes to make things work with Unity 5.6.1
    21. //March 2018
    22. //Added link to community thread, booleans to chose if scale and rotation are applied, mark scene as dirty, changed menu item to tools. By Hyper
    23.  
    24. public class ReplaceWithPrefab : EditorWindow
    25. {
    26.     public GameObject Prefab;
    27.     public GameObject[] ObjectsToReplace;
    28.     public List<GameObject> TempObjects = new List<GameObject>();
    29.     public bool KeepOriginalNames = true;
    30.     public bool EditMode = false;
    31.     public bool ApplyRotation = true;
    32.     public bool ApplyScale = true;
    33.     // Add menu named "My Window" to the Window menu
    34.     [MenuItem("Tools/ReplaceWithPrefab")]
    35.     static void Init()
    36.     {
    37.         // Get existing open window or if none, make a new one:
    38.         ReplaceWithPrefab window = (ReplaceWithPrefab)EditorWindow.GetWindow(typeof(ReplaceWithPrefab));
    39.         window.Show();
    40.     }
    41.     void OnSelectionChange()
    42.     {
    43.         GetSelection();
    44.         Repaint();
    45.     }
    46.     void OnGUI()
    47.     {
    48.         EditMode = GUILayout.Toggle(EditMode, "Edit");
    49.         if (GUI.changed)
    50.         {
    51.             if (EditMode)
    52.                 GetSelection();
    53.             else
    54.                 ResetPreview();
    55.         }
    56.         KeepOriginalNames = GUILayout.Toggle(KeepOriginalNames, "Keep names");
    57.         ApplyRotation = GUILayout.Toggle(ApplyRotation, "Apply rotation");
    58.         ApplyScale = GUILayout.Toggle(ApplyScale, "Apply scale");
    59.         GUILayout.Space(5);
    60.         if (EditMode)
    61.         {
    62.             ResetPreview();
    63.  
    64.             GUI.color = Color.yellow;
    65.             if (Prefab != null)
    66.             {
    67.                 GUILayout.Label("Prefab: ");
    68.                 GUILayout.Label(Prefab.name);
    69.             }
    70.             else
    71.             {
    72.                 GUILayout.Label("No prefab selected");
    73.             }
    74.             GUI.color = Color.white;
    75.  
    76.             GUILayout.Space(5);
    77.             GUILayout.BeginScrollView(new Vector2());
    78.             foreach (GameObject go in ObjectsToReplace)
    79.             {
    80.                 GUILayout.Label(go.name);
    81.                 if (Prefab != null)
    82.                 {
    83.                     GameObject newObject;
    84.                     newObject = (GameObject)PrefabUtility.InstantiatePrefab(Prefab);
    85.                     newObject.transform.SetParent(go.transform.parent, true);
    86.                     newObject.transform.localPosition = go.transform.localPosition;
    87.                     if (ApplyRotation)
    88.                     {
    89.                         newObject.transform.localRotation = go.transform.localRotation;
    90.                     }
    91.                     if (ApplyScale)
    92.                     {
    93.                         newObject.transform.localScale = go.transform.localScale;
    94.                     }
    95.                     TempObjects.Add(newObject);
    96.                     if (KeepOriginalNames)
    97.                         newObject.transform.name = go.transform.name;
    98.                     go.SetActive(false);
    99.                 }
    100.             }
    101.             GUILayout.EndScrollView();
    102.             GUILayout.Space(5);
    103.             GUILayout.BeginHorizontal();
    104.             if (GUILayout.Button("Apply"))
    105.             {
    106.                 foreach (GameObject go in ObjectsToReplace)
    107.                 {
    108.                     DestroyImmediate(go);
    109.                 }
    110.                 EditMode = false;
    111.                 EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene()); // So that we don't forget to save...
    112.             };
    113.             if (GUILayout.Button("Cancel"))
    114.             {
    115.                 ResetPreview();
    116.                 EditMode = false;
    117.             };
    118.             GUILayout.EndHorizontal();
    119.         }
    120.         else
    121.         {
    122.             ObjectsToReplace = new GameObject[0];
    123.             TempObjects.Clear();
    124.             Prefab = null;
    125.         }
    126.  
    127.     }
    128.     void OnDestroy()
    129.     {
    130.         ResetPreview();
    131.     }
    132.     void GetSelection()
    133.     {
    134.         if (EditMode && Selection.activeGameObject != null)
    135.         {
    136.             PrefabType t = PrefabUtility.GetPrefabType(Selection.activeGameObject);
    137.             if (t == PrefabType.Prefab) //Here goes the fix
    138.             {
    139.                 Prefab = Selection.activeGameObject;
    140.             }
    141.             else
    142.             {
    143.                 ResetPreview();
    144.                 ObjectsToReplace = Selection.gameObjects;
    145.             }
    146.         }
    147.     }
    148.     void ResetPreview()
    149.     {
    150.         if (TempObjects != null)
    151.         {
    152.             foreach (GameObject go in TempObjects)
    153.             {
    154.                 DestroyImmediate(go);
    155.             }
    156.         }
    157.         foreach (GameObject go in ObjectsToReplace)
    158.         {
    159.             go.SetActive(true);
    160.         }
    161.         TempObjects.Clear();
    162.     }
    163. }
     
    _creatio_ likes this.
  17. Arno1975

    Arno1975

    Joined:
    Aug 14, 2013
    Posts:
    40
    There is this posibility to add a sjon file, does anybody know what that does..

    my wish is to have a sjon file like,

    Generic model <716520 floor 1000x2431> , 716520 prefab floor 1000x2431

    So in my project look for all elements called Generic model <.....2431> and replace them with prefab 716520 prefab floor 1000x2431

    is this possible...
     
  18. apocaliptika

    apocaliptika

    Joined:
    Jul 22, 2017
    Posts:
    1
    This is an update from @_creatio_ and @Elzean 's and @Hypertectonic's version, with an extra bool for keeping the Child Index in the Hierarchy. It's an amazing script and made my life so much easier except for the fact that I had to keep resenting the sibling index.
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using UnityEditor.SceneManagement;
    4. using System.Collections.Generic;
    5.  
    6. // COMMUNITY THREAD LINK https://forum.unity.com/threads/replace-game-object-with-prefab.24311/
    7. // CopyComponents - by Michael L. Croswell for Colorado Game Coders, LLC
    8. // March 2010
    9. //Modified by Kristian Helle Jespersen
    10. //June 2011
    11. //Modified by Connor Cadellin McKee for Excamedia
    12. //April 2015
    13. //Modified by Fernando Medina (fermmmm)
    14. //April 2015
    15. //Modified by Julien Tonsuso (www.julientonsuso.com)
    16. //July 2015
    17. //Changed into editor window and added instant preview in scene view
    18. //Modified by Alex Dovgodko
    19. //June 2017
    20. //Made changes to make things work with Unity 5.6.1
    21. //March 2018
    22. //Added link to community thread, booleans to chose if scale and rotation are applied, mark scene as dirty, changed menu item to tools. By Hyper
    23. //May 2018
    24. //Added KeepPlaceInHeirarchy self explanatory
    25. //Modified by Virgil Iordan
    26. public class ReplaceWithPrefab:EditorWindow {
    27.     public GameObject Prefab;
    28.     public GameObject[] ObjectsToReplace;
    29.     public List<GameObject> TempObjects = new List<GameObject>();
    30.     public bool KeepOriginalNames = true;
    31.     public bool EditMode = false;
    32.     public bool ApplyRotation = true;
    33.     public bool ApplyScale = true;
    34.     public bool KeepPlaceInHeirarchy = false;
    35.     // Add menu named "My Window" to the Window menu
    36.     [MenuItem("Tools/ReplaceWithPrefab")]
    37.     static void Init() {
    38.         // Get existing open window or if none, make a new one:
    39.         ReplaceWithPrefab window = (ReplaceWithPrefab)EditorWindow.GetWindow(typeof(ReplaceWithPrefab));
    40.         window.Show();
    41.     }
    42.     void OnSelectionChange() {
    43.         GetSelection();
    44.         Repaint();
    45.     }
    46.  
    47.     void CheckParent() {
    48.     }
    49.  
    50.     void OnGUI() {
    51.         EditMode = GUILayout.Toggle(EditMode,"Edit");
    52.         if (GUI.changed) {
    53.             if (EditMode)
    54.                 GetSelection();
    55.             else
    56.                 ResetPreview();
    57.         }
    58.         KeepOriginalNames = GUILayout.Toggle(KeepOriginalNames,"Keep names");
    59.         ApplyRotation = GUILayout.Toggle(ApplyRotation,"Apply rotation");
    60.         ApplyScale = GUILayout.Toggle(ApplyScale,"Apply scale");
    61.         KeepPlaceInHeirarchy = GUILayout.Toggle(KeepPlaceInHeirarchy,"Keep Place In Heirarchy");
    62.         GUILayout.Space(5);
    63.         if (EditMode) {
    64.             ResetPreview();
    65.  
    66.             GUI.color = Color.yellow;
    67.             if (Prefab != null) {
    68.                 GUILayout.Label("Prefab: ");
    69.                 GUILayout.Label(Prefab.name);
    70.             } else {
    71.                 GUILayout.Label("No prefab selected");
    72.             }
    73.             GUI.color = Color.white;
    74.  
    75.             GUILayout.Space(5);
    76.             GUILayout.BeginScrollView(new Vector2());
    77.             foreach (GameObject go in ObjectsToReplace) {
    78.                 GUILayout.Label(go.name);
    79.                 if (Prefab != null) {
    80.                     GameObject newObject;
    81.                     newObject = (GameObject)PrefabUtility.InstantiatePrefab(Prefab);
    82.                     newObject.transform.SetParent(go.transform.parent,true);
    83.                     newObject.transform.localPosition = go.transform.localPosition;
    84.                     if (ApplyRotation) {
    85.                         newObject.transform.localRotation = go.transform.localRotation;
    86.                     }
    87.                     if (ApplyScale) {
    88.                         newObject.transform.localScale = go.transform.localScale;
    89.                     }
    90.                     TempObjects.Add(newObject);
    91.                     if (KeepOriginalNames) {
    92.                         newObject.transform.name = go.transform.name;
    93.                     }
    94.                     go.SetActive(false);
    95.                     if (KeepPlaceInHeirarchy) {
    96.                         newObject.transform.SetSiblingIndex(go.transform.GetSiblingIndex());
    97.                     }
    98.                 }
    99.             }
    100.             GUILayout.EndScrollView();
    101.             GUILayout.Space(5);
    102.             GUILayout.BeginHorizontal();
    103.             if (GUILayout.Button("Apply")) {
    104.                 foreach (GameObject go in ObjectsToReplace) {
    105.                     DestroyImmediate(go);
    106.                 }
    107.                 EditMode = false;
    108.                 EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene()); // So that we don't forget to save...
    109.             };
    110.             if (GUILayout.Button("Cancel")) {
    111.                 ResetPreview();
    112.                 EditMode = false;
    113.             };
    114.             GUILayout.EndHorizontal();
    115.         } else {
    116.             ObjectsToReplace = new GameObject[0];
    117.             TempObjects.Clear();
    118.             Prefab = null;
    119.         }
    120.  
    121.     }
    122.     void OnDestroy() {
    123.         ResetPreview();
    124.     }
    125.     void GetSelection() {
    126.         if (EditMode && Selection.activeGameObject != null) {
    127.             PrefabType t = PrefabUtility.GetPrefabType(Selection.activeGameObject);
    128.             if (t == PrefabType.Prefab) //Here goes the fix
    129.             {
    130.                 Prefab = Selection.activeGameObject;
    131.             } else {
    132.                 ResetPreview();
    133.                 ObjectsToReplace = Selection.gameObjects;
    134.             }
    135.         }
    136.     }
    137.     void ResetPreview() {
    138.         if (TempObjects != null) {
    139.             foreach (GameObject go in TempObjects) {
    140.                 DestroyImmediate(go);
    141.             }
    142.         }
    143.         foreach (GameObject go in ObjectsToReplace) {
    144.             go.SetActive(true);
    145.         }
    146.         TempObjects.Clear();
    147.     }
    148. }
     
    NeatWolf likes this.
  19. Paul-Swanson

    Paul-Swanson

    Joined:
    Jan 22, 2014
    Posts:
    286
    Old thread, I know, and I don't care. Consider this a sticky, since this was so useful. Magnificent
     
  20. NeatWolf

    NeatWolf

    Joined:
    Sep 27, 2013
    Posts:
    875
    I needed this right today, thanks guys! :)
     
  21. Creepy-Cat

    Creepy-Cat

    Joined:
    Dec 4, 2013
    Posts:
    687
    Sorry for bump, but thanks for this script, you just save my life on a big gameobject replacing process... Usually i do those crap by hand...
     
  22. Paul-Swanson

    Paul-Swanson

    Joined:
    Jan 22, 2014
    Posts:
    286
    This really needs to be a built in feature....just saying *winkwink nudge nudge*
     
    Hypertectonic and Creepy-Cat like this.
  23. master_rigel

    master_rigel

    Joined:
    Mar 24, 2014
    Posts:
    62
    I am now using this script. I've bookmarked this page for later.
     
  24. alargastudio

    alargastudio

    Joined:
    Apr 18, 2017
    Posts:
    11
    awesome script, you guys just save my lives
    thank you so much!
     
  25. bansheesoft

    bansheesoft

    Joined:
    Oct 3, 2014
    Posts:
    54
    Quickly tossed this together if anyone needs it off this code.
    Drop the prefab to use to replace in the top field then the selected are in the list out. Apply to switch out..
    Simple and works. Only tested a little but it is doing my job.
    Thanks!

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. // CopyComponents - by Michael L. Croswell for Colorado Game Coders, LLC
    4. // March 2010
    5. //Modified by Kristian Helle Jespersen
    6. //June 2011
    7. //Modified by Connor Cadellin McKee for Excamedia
    8. //April 2015
    9. //Modified by Fernando Medina (fermmmm)
    10. //April 2015
    11. //Modified  by Ryan Mitchell (RyanMitchellGames.WordPress.com)
    12. //January 2019
    13.  
    14. public class ReplaceGameObjects : ScriptableWizard
    15. {
    16.     public GameObject[] ObjectsToReplace;
    17.     Object obj = null;
    18.  
    19.     [MenuItem("Tools/Replace GameObjects")]
    20.     static void CreateWizard()
    21.     {
    22.         ReplaceGameObjects window = ScriptableObject.CreateInstance(typeof(ReplaceGameObjects)) as ReplaceGameObjects;
    23.         window.ShowUtility();
    24.     }
    25.  
    26.     void Apply()
    27.     {
    28.         Object[] gos = Selection.objects;
    29.         foreach (Object go in  gos)
    30.         {
    31.             GameObject oldObject = go as GameObject;
    32.             GameObject newObjectHold = obj as GameObject;
    33.             if (oldObject &&
    34.                 newObjectHold)
    35.             {
    36.                 GameObject newObject = (GameObject)PrefabUtility.InstantiatePrefab(newObjectHold);
    37.  
    38.                 newObject.transform.SetParent(oldObject.transform.parent, true);
    39.                 newObject.transform.localPosition = oldObject.transform.localPosition;
    40.                 newObject.transform.localRotation = oldObject.transform.localRotation;
    41.                 newObject.transform.localScale = oldObject.transform.localScale;
    42.                 newObject.transform.name = oldObject.transform.name;
    43.                 DestroyImmediate(go);
    44.             }
    45.         }
    46.     }
    47.  
    48.     void OnGUI()
    49.     {
    50.         obj = EditorGUILayout.ObjectField("Label:", obj, typeof(GameObject), true);
    51.  
    52.         string selectedName = "Selected:\r\n";
    53.         Object[] gos = Selection.objects;
    54.         foreach (Object go in gos)
    55.         {
    56.             selectedName += go.name + "\r\n";
    57.         }
    58.         EditorGUILayout.TextArea( selectedName);
    59.  
    60.         if (GUILayout.Button("Apply"))
    61.             Apply();
    62.  
    63.         if (GUILayout.Button("Close"))
    64.             Close();
    65.  
    66.     }
    67.  
    68.     void OnInspectorUpdate()
    69.     {
    70.         Repaint();
    71.     }
    72. }
     
    Anthony0506 likes this.
  26. Anthony0506

    Anthony0506

    Joined:
    Oct 13, 2016
    Posts:
    84
    hey banshee that works great, thanks. itd be sweet if the apply button was at the top of the gui for when dealing with hundreds of objects, or if clicking enter would apply it, as otherwise the button goes off screen. as is you'd have to do it in groups of like 30 or less, but still works. probably just a matter of moving a couple lines. thanks again.
     
  27. dbyeajee_RaveAC

    dbyeajee_RaveAC

    Joined:
    Mar 23, 2018
    Posts:
    1
    Building on the shoulders of giants @apocaliptika, @Elzean , @Hypertectonic , @_creatio_ . Sorry if I missed anyone.
    Added numbering to the instantiated prefabs as an identifier, also checks for numbers used already.
    Follows the default Unity naming convention i.e. "Cube (1)"
    Finds the "space" character in the name to identify where the number is, then strips the brackets.
    The code is not that elegant and doesn't account for custom naming conventions, but hopefully someone can improve it.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using UnityEditor.SceneManagement;
    4. using System.Collections.Generic;
    5. // COMMUNITY THREAD LINK https://forum.unity.com/threads/replace-game-object-with-prefab.24311/
    6. // CopyComponents - by Michael L. Croswell for Colorado Game Coders, LLC
    7. // March 2010
    8. //Modified by Kristian Helle Jespersen
    9. //June 2011
    10. //Modified by Connor Cadellin McKee for Excamedia
    11. //April 2015
    12. //Modified by Fernando Medina (fermmmm)
    13. //April 2015
    14. //Modified by Julien Tonsuso (www.julientonsuso.com)
    15. //July 2015
    16. //Changed into editor window and added instant preview in scene view
    17. //Modified by Alex Dovgodko
    18. //June 2017
    19. //Made changes to make things work with Unity 5.6.1
    20. //March 2018
    21. //Added link to community thread, booleans to chose if scale and rotation are applied, mark scene as dirty, changed menu item to tools. By Hyper
    22. //May 2018
    23. //Added KeepPlaceInHeirarchy self explanatory
    24. //Modified by Virgil Iordan
    25. //Added unique numbering identifier in the hierarchy to each newly instantiated prefab, also accounts for existing numbers
    26. //Modified by Dev Bye-A-Jee, Sanjay Sen & Nick Rodriguez for Ravensbourne University London
    27. //January 2019
    28. public class ReplaceWithPrefab:EditorWindow {
    29.     public GameObject Prefab;
    30.     public GameObject[] ObjectsToReplace;
    31.     public List<GameObject> TempObjects = new List<GameObject>();
    32.     public bool KeepOriginalNames = true;
    33.     public bool EditMode = false;
    34.     public bool ApplyRotation = true;
    35.     public bool ApplyScale = true;
    36.     public bool KeepPlaceInHeirarchy = false;
    37.     // Add menu named "My Window" to the Window menu
    38.     [MenuItem("Tools/ReplaceWithPrefab")]
    39.     static void Init() {
    40.         // Get existing open window or if none, make a new one:
    41.         ReplaceWithPrefab window = (ReplaceWithPrefab)EditorWindow.GetWindow(typeof(ReplaceWithPrefab));
    42.         window.Show();
    43.     }
    44.     void OnSelectionChange() {
    45.         GetSelection();
    46.         Repaint();
    47.     }
    48.     void CheckParent() {
    49.     }
    50.     void OnGUI() {
    51.         EditMode = GUILayout.Toggle(EditMode,"Edit");
    52.         if (GUI.changed) {
    53.             if (EditMode)
    54.                 GetSelection();
    55.             else
    56.                 ResetPreview();
    57.         }
    58.         KeepOriginalNames = GUILayout.Toggle(KeepOriginalNames,"Keep names");
    59.         ApplyRotation = GUILayout.Toggle(ApplyRotation,"Apply rotation");
    60.         ApplyScale = GUILayout.Toggle(ApplyScale,"Apply scale");
    61.         KeepPlaceInHeirarchy = GUILayout.Toggle(KeepPlaceInHeirarchy,"Keep Place In Hierarchy");
    62.         GUILayout.Space(5);
    63.         if (EditMode) {
    64.             ResetPreview();
    65.             GUI.color = Color.yellow;
    66.             if (Prefab != null) {
    67.                 GUILayout.Label("Prefab: ");
    68.                 GUILayout.Label(Prefab.name);
    69.             } else {
    70.                 GUILayout.Label("No prefab selected");
    71.             }
    72.             GUI.color = Color.white;
    73.             GUILayout.Space(5);
    74.             GUILayout.BeginScrollView(new Vector2());
    75.             foreach (GameObject go in ObjectsToReplace) {
    76.                 GUILayout.Label(go.name);
    77.                 if (Prefab != null) {
    78.                     GameObject newObject;
    79.                     newObject = (GameObject)PrefabUtility.InstantiatePrefab(Prefab);
    80.                     newObject.transform.SetParent(go.transform.parent,true);
    81.                     newObject.transform.localPosition = go.transform.localPosition;
    82.                     if (ApplyRotation) {
    83.                         newObject.transform.localRotation = go.transform.localRotation;
    84.                     }
    85.                     if (ApplyScale) {
    86.                         newObject.transform.localScale = go.transform.localScale;
    87.                     }
    88.                     TempObjects.Add(newObject);
    89.              
    90.                     if (KeepOriginalNames) {
    91.                         newObject.transform.name = go.transform.name;
    92.                     }
    93.                     go.SetActive(false);
    94.                  
    95.                     if (KeepPlaceInHeirarchy) {
    96.                         newObject.transform.SetSiblingIndex(go.transform.GetSiblingIndex());
    97.                     }
    98.                 }
    99.             }
    100.             GUILayout.EndScrollView();
    101.             GUILayout.Space(5);
    102.             GUILayout.BeginHorizontal();
    103.             if (GUILayout.Button("Apply")) {
    104.                 if (!KeepOriginalNames) {
    105.                     int count = 0;
    106.                     List<int> ExistingNumbers = new List<int>();
    107.                     foreach (GameObject obj in Object.FindObjectsOfType(typeof(GameObject)))
    108.                     {
    109.                         if (obj.name.Contains(Prefab.name))
    110.                         {
    111.                             string[] stringSplit = obj.name.Split(' '); // number deliminator, setup for default Unity naming convention i.e "Cube (1)"
    112.                             if (stringSplit.Length > 1) {
    113.                                 char[] charsToTrim = {'(', ')'}; // extra characters to trim
    114.                                  string num = stringSplit[1].Trim(charsToTrim); // substring which contains number
    115.                                 int x = int.Parse(num); // convert string to number
    116.                                 ExistingNumbers.Add(x);
    117.                              }
    118.                         }
    119.                     }
    120.                     foreach (GameObject go in TempObjects) {
    121.                         count++;
    122.                          if (ExistingNumbers.Count > 0) {
    123.                             int i = 0;
    124.                             while (i < (ExistingNumbers.Count)) {
    125.                                 if (count == (ExistingNumbers[i])) {
    126.                                     count++;
    127.                                     i = 0;
    128.                                 } else {
    129.                                     i++;
    130.                                 }
    131.                             }
    132.                         }
    133.                         go.transform.name = go.transform.name + " (" + count + ")";
    134.                     }
    135.                 }
    136.                 foreach (GameObject go in ObjectsToReplace) {
    137.                     DestroyImmediate(go);
    138.                 }
    139.                 EditMode = false;
    140.                 EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene()); // So that we don't forget to save...
    141.             };
    142.             if (GUILayout.Button("Cancel")) {
    143.                 ResetPreview();
    144.                 EditMode = false;
    145.             };
    146.             GUILayout.EndHorizontal();
    147.         } else {
    148.             ObjectsToReplace = new GameObject[0];
    149.             TempObjects.Clear();
    150.             Prefab = null;
    151.         }
    152.     }
    153.     void OnDestroy() {
    154.         ResetPreview();
    155.     }
    156.     void GetSelection() {
    157.         if (EditMode && Selection.activeGameObject != null) {
    158.             PrefabType t = PrefabUtility.GetPrefabType(Selection.activeGameObject);
    159.             if (t == PrefabType.Prefab) //Here goes the fix
    160.             {
    161.                 Prefab = Selection.activeGameObject;
    162.             } else {
    163.                 ResetPreview();
    164.                 ObjectsToReplace = Selection.gameObjects;
    165.             }
    166.         }
    167.     }
    168.     void ResetPreview() {
    169.         if (TempObjects != null) {
    170.             foreach (GameObject go in TempObjects) {
    171.                 DestroyImmediate(go);
    172.             }
    173.         }
    174.         foreach (GameObject go in ObjectsToReplace) {
    175.             go.SetActive(true);
    176.         }
    177.         TempObjects.Clear();
    178.     }
    179. }
     
    sarebots2, Hypertectonic and Elzean like this.
  28. dubiduboni_unity

    dubiduboni_unity

    Joined:
    Feb 11, 2019
    Posts:
    116
    My script.

    I added a search bar to easily searching for objects to replace. for example type in Cube(Clone) or Cube and it will find all the Cube objects in the Hierarchy including children and will replace them with a button click.

    Or a single replace.

    Added keep names option and undo option.
    Also it keep the replaced objects index place in the hierarchy and also if you have more then one scenes it will keep the place of the replaced gameobject according to on what scene it was changed.



    Code (csharp):
    1.  
    2. using System;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5. using System.IO;
    6. using System.Linq;
    7. using UnityEditor;
    8. using UnityEngine;
    9. using UnityEngine.SceneManagement;
    10. using UnityEngine.UI;
    11.  
    12. public class PrefabReplace : EditorWindow
    13. {
    14.     [SerializeField] private GameObject prefab;
    15.     private bool selectionChanged;
    16.     private string objectsToSearch = "";
    17.     private List<GameObject> foundObjects = new List<GameObject>();
    18.     private GUIStyle guiStyle = new GUIStyle(); //create a new variable
    19.     private int count = 0;
    20.     private bool addFoundObjects;
    21.     private bool keepNames = true;
    22.  
    23.     [MenuItem("Tools/Prefab Replace")]
    24.     static void CreateReplaceWithPrefab()
    25.     {
    26.         int width = 340;
    27.         int height = 370;
    28.  
    29.         int x = (Screen.currentResolution.width - width) / 2;
    30.         int y = (Screen.currentResolution.height - height) / 2;
    31.      
    32.         GetWindow<PrefabReplace>().position = new Rect(x, y, width, height);
    33.     }
    34.  
    35.     private void OnGUI()
    36.     {
    37.         guiStyle.fontSize = 15; //change the font size
    38.         Searching();
    39.         GUILayout.Space(10);
    40.         Replacing();
    41.         GUILayout.Space(50);
    42.         Settings();
    43.     }
    44.  
    45.     private void Searching()
    46.     {
    47.         //GUI.Label(new Rect(10, 15, 150, 20), "Search by name", guiStyle);
    48.         objectsToSearch = GUI.TextField(new Rect(90, 35, 150, 20), objectsToSearch, 25);
    49.  
    50.         if (objectsToSearch != "")
    51.         {
    52.             GUI.enabled = true;
    53.         }
    54.         else
    55.         {
    56.             GUI.enabled = false;
    57.             count = 0;
    58.         }
    59.         GUILayout.Space(15);
    60.         if (GUILayout.Button("Search"))
    61.         {
    62.             foundObjects = new List<GameObject>();
    63.             count = 0;
    64.  
    65.             foreach (GameObject gameObj in GameObject.FindObjectsOfType<GameObject>())
    66.             {
    67.                 if (gameObj.name == objectsToSearch)//.Contains(objectsToSearch))// == objectsToSearch)
    68.                 {
    69.                     count += 1;
    70.                     foundObjects.Add(gameObj);
    71.                     foreach (Transform child in gameObj.transform)
    72.                     {
    73.                         count += 1;
    74.                         foundObjects.Add(child.gameObject);
    75.                     }
    76.                 }
    77.             }
    78.  
    79.             if(foundObjects.Count == 0)
    80.             {
    81.                 count = 0;
    82.             }
    83.         }
    84.  
    85.         GUI.enabled = true;
    86.         EditorGUI.LabelField(new Rect(90, 65, 210, 15), "Number of found objects and childs");
    87.         GUI.TextField(new Rect(90, 80, 60, 15), count.ToString(), 25);
    88.  
    89.         GUILayout.Space(100);
    90.         if (count > 0)
    91.         {
    92.             GUI.enabled = true;
    93.         }
    94.         else
    95.         {
    96.             GUI.enabled = false;
    97.         }
    98.         if (GUILayout.Button("Replace found objects"))
    99.         {
    100.             if (prefab != null)      
    101.             {
    102.                 InstantiatePrefab(foundObjects);
    103.             }
    104.         }
    105.  
    106.         GUI.enabled = true;
    107.     }
    108.  
    109.     private void Replacing()
    110.     {
    111.         GUILayout.Space(20);
    112.         GUILayout.BeginVertical(GUI.skin.box);
    113.         GUILayout.Label("Replacing");
    114.         GUILayout.Space(20);
    115.  
    116.         prefab = (GameObject)EditorGUILayout.ObjectField("Prefab", prefab, typeof(GameObject), false);
    117.  
    118.         var selection = Selection.objects.OfType<GameObject>().ToList();
    119.  
    120.         if (selectionChanged)
    121.         {
    122.             if (selection.Count == 0)
    123.                 GUI.enabled = false;
    124.  
    125.             for (var i = selection.Count - 1; i >= 0; --i)
    126.             {
    127.                 var selectedObject = selection[i];
    128.                 if (prefab != null && selection.Count > 0 &&
    129.                     selectedObject.scene.name != null
    130.                     && prefab != PrefabUtility
    131.                     .GetCorrespondingObjectFromSource(selectedObject))
    132.                 {
    133.                     GUI.enabled = true;
    134.                 }
    135.                 else
    136.                 {
    137.                     GUI.enabled = false;
    138.                 }
    139.             }
    140.         }
    141.         else
    142.         {
    143.             GUI.enabled = false;
    144.         }
    145.  
    146.         if (GUILayout.Button("Replace"))
    147.         {
    148.             InstantiatePrefab(selection);
    149.             selectionChanged = false;
    150.         }
    151.  
    152.         GUILayout.Space(10);
    153.         GUI.enabled = true;
    154.         EditorGUILayout.LabelField("Selection count: " + Selection.objects.OfType<GameObject>().Count());
    155.  
    156.         GUILayout.EndVertical();
    157.     }
    158.  
    159.     private void Settings()
    160.     {
    161.         keepNames = GUILayout.Toggle(keepNames, "Keep Names");
    162.     }
    163.  
    164.     private void OnInspectorUpdate()
    165.     {
    166.         Repaint();
    167.     }
    168.  
    169.     private void OnSelectionChange()
    170.     {
    171.         selectionChanged = true;
    172.     }
    173.  
    174.     private void InstantiatePrefab(List<GameObject> selection)
    175.     {
    176.         if (prefab != null && selection.Count > 0)
    177.         {
    178.             for (var i = selection.Count - 1; i >= 0; --i)
    179.             {
    180.                 var selected = selection[i];
    181.                 Component[] components = selected.GetComponents(typeof(MonoBehaviour));
    182.                 if (components.Length == 0)
    183.                 {
    184.                     SceneManager.SetActiveScene(SceneManager.GetSceneByName(selected.scene.name));
    185.  
    186.                     var prefabType = PrefabUtility.GetPrefabAssetType(prefab);
    187.                     GameObject newObject;
    188.  
    189.                     if (prefabType == PrefabAssetType.Regular)
    190.                     {
    191.                         newObject = (GameObject)PrefabUtility.InstantiatePrefab(prefab);
    192.                     }
    193.                     else
    194.                     {
    195.                         newObject = Instantiate(prefab);
    196.  
    197.                         if (keepNames == false)
    198.                         {
    199.                             newObject.name = prefab.name;
    200.                         }
    201.                     }
    202.                     if (newObject == null)
    203.                     {
    204.                         Debug.LogError("Error instantiating prefab");
    205.                         break;
    206.                     }
    207.  
    208.                     Undo.RegisterCreatedObjectUndo(newObject, "Replace With Prefabs");
    209.                     newObject.transform.parent = selected.transform.parent;
    210.                     newObject.transform.localPosition = selected.transform.localPosition;
    211.                     newObject.transform.localRotation = selected.transform.localRotation;
    212.                     newObject.transform.localScale = selected.transform.localScale;
    213.                     newObject.transform.SetSiblingIndex(selected.transform.GetSiblingIndex());
    214.                     if (keepNames == true)
    215.                     {
    216.                         newObject.name = selected.name;
    217.                     }
    218.                     Undo.DestroyObjectImmediate(selected);
    219.                 }
    220.             }
    221.         }
    222.     }
    223. }
    224.  
     
  29. phobos2077

    phobos2077

    Joined:
    Feb 10, 2018
    Posts:
    68
    Yes another version but with slightly different task. I already used a bunch of prefabs on several scenes and needed to replace every instance of each prefab with a new version (regular prefabs with variant prefabs).
    So you open this window, put all of your old prefabs in the first array, then all of corresponding new prefabs in the second array (must be in the same order). Then you open your old scenes one by one and just press the button, it will replace everything for you. No need to search and selecting anything.

    Code (CSharp):
    1.  
    2. using System;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEditor;
    6. using UnityEngine.SceneManagement;
    7.  
    8. public class ReplacePrefabs : EditorWindow
    9. {
    10.     [SerializeField]
    11.     private GameObject[] oldPrefabs;
    12.  
    13.     [SerializeField]
    14.     private GameObject[] newPrefabs;
    15.  
    16.     private SerializedObject serialized;
    17.  
    18.     private void OnEnable()
    19.     {
    20.         serialized = new SerializedObject(this);
    21.     }
    22.  
    23.     [MenuItem("Tools/Replace Prefabs")]
    24.     static void CreateReplaceWithPrefab()
    25.     {
    26.         EditorWindow.GetWindow<ReplacePrefabs>();
    27.     }
    28.  
    29.     private void OnGUI()
    30.     {
    31.         EditorGUILayout.PropertyField(serialized.FindProperty(nameof(oldPrefabs)), new GUIContent("Old Prefabs"), true);
    32.         EditorGUILayout.PropertyField(serialized.FindProperty(nameof(newPrefabs)), new GUIContent("New Prefabs"), true);
    33.         serialized.ApplyModifiedProperties();
    34.  
    35.         if (GUILayout.Button("Replace"))
    36.         {
    37.             var replaceDict = new Dictionary<GameObject, GameObject>();
    38.             var numPairs = Mathf.Min(oldPrefabs.Length, newPrefabs.Length);
    39.             for (int i = 0; i < numPairs; i++)
    40.             {
    41.                 if (oldPrefabs[i] && newPrefabs[i] && PrefabUtility.IsPartOfAnyPrefab(newPrefabs[i]))
    42.                 {
    43.                     replaceDict.Add(oldPrefabs[i], newPrefabs[i]);
    44.                 }
    45.             }
    46.  
    47.             var scene = SceneManager.GetActiveScene();
    48.             var rootObjects = scene.GetRootGameObjects();
    49.             int replaceCount = 0;
    50.             foreach (var go in rootObjects)
    51.             {
    52.                 replaceCount += ReplaceForObjectRecursive(go, replaceDict);
    53.             }
    54.             Debug.Log($"Replaced {replaceCount} game objects.");
    55.         }
    56.  
    57.         GUI.enabled = false;
    58.     }
    59.  
    60.     private int ReplaceForObjectRecursive(GameObject go, Dictionary<GameObject, GameObject> replaceDict)
    61.     {
    62.         var sourcePrefab = GetObjectPrefab(go);
    63.         if (!sourcePrefab || !replaceDict.ContainsKey(sourcePrefab))
    64.         {
    65.             int replaceCount = 0;
    66.             foreach (Transform child in go.transform)
    67.             {
    68.                 replaceCount += ReplaceForObjectRecursive(child.gameObject, replaceDict);
    69.             }
    70.             return replaceCount;
    71.         }
    72.  
    73.         var prefab = replaceDict[sourcePrefab];
    74.         var newObject = (GameObject)PrefabUtility.InstantiatePrefab(prefab);
    75.         if (newObject == null)
    76.         {
    77.             Debug.LogError("Error instantiating prefab");
    78.             return 0;
    79.         }
    80.  
    81.         Undo.RegisterCreatedObjectUndo(newObject, "Replace Prefabs");
    82.         newObject.transform.parent = go.transform.parent;
    83.         newObject.transform.localPosition = go.transform.localPosition;
    84.         newObject.transform.localRotation = go.transform.localRotation;
    85.         newObject.transform.localScale = go.transform.localScale;
    86.         newObject.transform.SetSiblingIndex(go.transform.GetSiblingIndex());
    87.         Undo.DestroyObjectImmediate(go);
    88.         return 1;
    89.     }
    90.  
    91.     private GameObject GetObjectPrefab(GameObject instance)
    92.     {
    93.         var root = PrefabUtility.GetNearestPrefabInstanceRoot(instance);
    94.         return root ? PrefabUtility.GetCorrespondingObjectFromSource(root) : null;
    95.     }
    96. }
    97.  
    PS: I wouldn't have needed this if Unity had better logic for replacing prefab assets. If I just drag the new prefab asset on the old one, Unity prompts for replacement and it will replace the instances in every scene. The problem is transform will be reset as well - this makes such replacement useless if you have already placed the old prefab in your scenes. It could still be useful for prefabs are never placed in scenes but always instantiated.
     
    Hypertectonic likes this.
  30. rohitvishwakarma1819

    rohitvishwakarma1819

    Joined:
    Feb 15, 2018
    Posts:
    6
    Thanks but the transform of the gameobject are not copying into the prefab instance.
     
  31. deLord

    deLord

    Joined:
    Oct 11, 2014
    Posts:
    257
    Not sure if I used an unripe version of the script but from what I see nobody took into consideration that these objects may be referenced by other GameObjects:
    My HUDManager GO has a reference to several buttons. Using Alt + Drag-Prefab will just override the old one WITHOUT the possibility of using undo, so save before you try this out!
    The script does properly replace the object with the prefab but the references are destroyed. Also, buttons do not save their onClick() contents. And for me these were the main reason I searched for a solution :)
     
    leni8ec and NeatWolf like this.
unityunity