Replace game object with prefab?

Discussion in 'Unity Support' started by DaveA, Jun 4, 2009.

  1. DaveA

    DaveA

    Member

    Joined:
    Apr 15, 2009
    Messages:
    270
    I know I can replace a prefab with a game object, but can I do the reverse? Meaning, I want to keep the same settings, at LEAST the transform, of the GO, but replace it with a prefab.

    Would make importing game objects to other scenes a little more do-able.

    Gotta be a way to script that.
  2. Lucas Meijer

    Lucas Meijer

    New Member

    Joined:
    Apr 5, 2008
    Messages:
    436
    If I'm not mistaken, this is actually default behaviour. A prefab instance always has its transform settings as "overriden". So you can move the instance around, then change the prefab, and the instance will take on all settings from the prefab, except its transform settings.

    Bye, Lucas
  3. DaveA

    DaveA

    Member

    Joined:
    Apr 15, 2009
    Messages:
    270
    I should have been more clear.

    I don't want to change settings on the prefab. I want to REPLACE the ENTIRE prefab with another.

    Example:
    I make a nice particle effect. I place this in the scene in several places. Then, my partner makes a better effect on his computer. I want to replace my particles with his, so I copy his prefab to my project.

    But now, there is no way for me (that I know of!) to replace my prefab with his.
  4. MatthewW

    MatthewW

    Member

    Joined:
    Nov 30, 2006
    Messages:
    1,260
    Just drag an instance of his prefab from the scene hierarchy to the project pane, overriding your existing prefab.
  5. DaveA

    DaveA

    Member

    Joined:
    Apr 15, 2009
    Messages:
    270
    Thanks.

    Now the hard part: say you have a game object that contains one or more objects that you want to replace with prefabs. Think of them as place-holder objects. Now I want to replace the place-holders with prefabs, but without having to copy/paste all the params around. Is there a way to do that?
  6. sunset

    sunset

    New Member

    Joined:
    Nov 7, 2010
    Messages:
    61
    Hey,
    i had the same problem and wrote a little script to fix it.
    Its realy not that hard as I thougt ^^

    What it does:
    The script lets you replace a hole bunch of placeholders at the same by an predefined Prefab.
    The object you put in for replacing needs to be a Prefab.

    If you want to replace many placeholders at the same time, attach them as children to another Object. For example an
    Empty. Then declare this Parent as the object to replace.
    The script will automaticly check for its children an replace them.

    Feel free to do some improvements on the script. But please be fair enough to share it.
    So others could benefit of it.
  7. Ravael

    Ravael

    New Member

    Joined:
    Jan 6, 2011
    Messages:
    1
    INSTANCE REPLACEMENT:

    Drag your new Prefab onto the existing GameObject in the Hierarchy while holding [Alt].
    Last edited: Jan 6, 2011
  8. KristianHJ

    KristianHJ

    Member

    Joined:
    May 28, 2010
    Messages:
    27
    Hi

    I changed the script to allow for changing any number of gameobjects with a specific prefab.
    It also keeps the originals parents transform

    Code (csharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using System.Collections;
    4. // CopyComponents - by Michael L. Croswell for Colorado Game Coders, LLC
    5. // March 2010
    6.  
    7. //Modified by Kristian Helle Jespersen
    8. //June 2011
    9.  
    10. public class ReplaceGameObjects : ScriptableWizard
    11. {
    12.     public bool copyValues = true;
    13.     public GameObject NewType;
    14.     public GameObject[] OldObjects;
    15.  
    16.     [MenuItem("Custom/Replace GameObjects")]
    17.  
    18.  
    19.     static void CreateWizard()
    20.     {
    21.         ScriptableWizard.DisplayWizard("Replace GameObjects", typeof(ReplaceGameObjects), "Replace");
    22.     }
    23.  
    24.     void OnWizardCreate()
    25.     {
    26.         //Transform[] Replaces;
    27.         //Replaces = Replace.GetComponentsInChildren<Transform>();
    28.  
    29.         foreach (GameObject go in OldObjects)
    30.         {
    31.             GameObject newObject;
    32.             newObject = (GameObject)EditorUtility.InstantiatePrefab(NewType);
    33.             newObject.transform.position = go.transform.position;
    34.             newObject.transform.rotation = go.transform.rotation;
    35.             newObject.transform.parent = go.transform.parent;
    36.  
    37.             DestroyImmediate(go);
    38.  
    39.         }
    40.  
    41.     }
    42. }
  9. Metron

    Metron

    Member

    Joined:
    Aug 24, 2009
    Messages:
    704
    Great script... thanks...
  10. Eyeofgod

    Eyeofgod

    Member

    Joined:
    Jun 25, 2010
    Messages:
    110
    Many thanks. It has safe me a lot of work hours
  11. megmaltese

    megmaltese

    Member

    Joined:
    Mar 19, 2009
    Messages:
    1,897
    Thank you Kudos, this should be a standard Unity function imho...
  12. morphus1

    morphus1

    New Member

    Joined:
    Apr 9, 2012
    Messages:
    2
    Heya guys,
    I'm having a hard time trying to get this to work in my situation. The alt drag doesn't work for either. It says that this is not implemented yet. As for the script it says it can't find the prefab in the prefab library. any ideas?
  13. StubbornMinion

    StubbornMinion

    New Member

    Joined:
    Apr 13, 2012
    Messages:
    4
    Hey, I just registered on the community to say thank you to sunset and kudosforludos for this script. It totally worked and saved me a lot of bother :)
  14. DanTreble

    DanTreble

    Member

    Joined:
    Aug 31, 2010
    Messages:
    515
    Excellent script. I modified it slightly so it copies scale and it prefills the selection

    Code (csharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using System.Collections;
    4.  
    5. // CopyComponents - by Michael L. Croswell for Colorado Game Coders, LLC
    6. // March 2010
    7.  
    8. //Modified by Kristian Helle Jespersen
    9. //June 2011
    10.  
    11. public class ReplaceGameObjects : ScriptableWizard
    12. {
    13.     public bool copyValues = true;
    14.     public GameObject NewType;
    15.     public GameObject[] OldObjects;
    16.  
    17.     [MenuItem("Custom/Replace GameObjects")]
    18.     static void CreateWizard()
    19.     {
    20.         var replaceGameObjects = ScriptableWizard.DisplayWizard <ReplaceGameObjects>("Replace GameObjects", "Replace");
    21.         replaceGameObjects.OldObjects = Selection.gameObjects;
    22.     }
    23.  
    24.     void OnWizardCreate()
    25.     {
    26.         //Transform[] Replaces;
    27.         //Replaces = Replace.GetComponentsInChildren<Transform>();
    28.  
    29.         foreach (GameObject go in OldObjects)
    30.         {
    31.             GameObject newObject;
    32.             newObject = (GameObject)EditorUtility.InstantiatePrefab(NewType);
    33.             newObject.transform.parent = go.transform.parent;
    34.             newObject.transform.localPosition = go.transform.localPosition;
    35.             newObject.transform.localRotation = go.transform.localRotation;
    36.             newObject.transform.localScale = go.transform.localScale;
    37.  
    38.             DestroyImmediate(go);
    39.         }
    40.     }
    41.  
    42. }
  15. Morgan

    Morgan

    Member

    Joined:
    May 21, 2006
    Messages:
    1,169
    Same Here (3.5.2) - Alt-dragging a prefab from Project into a different prefab in Hierachy does not swap in the new prefab. It does nothing. (And occasionally crashes.) I don’t need the script and didn’t try it, but dragging manually would be great!
  16. .Rattlehead

    .Rattlehead

    Member

    Joined:
    Aug 4, 2011
    Messages:
    228
    I know this is an old thread but thanks ALOT, because this is saving me a lot of work (and nerves).
  17. ojgang

    ojgang

    New Member

    Joined:
    Oct 22, 2012
    Messages:
    2
    im totally noob in this....
    how to apply this script on my prefab ?
  18. kimberleyhansen

    kimberleyhansen

    New Member

    Joined:
    Oct 10, 2011
    Messages:
    1
    Yeah, sorry guys, I also don't know how to make this work. I've created a new script (CopyComponents.cs), and the Custom > ReplaceGameObjects menu shows up...but when I try to use the option, I get a "NullReferenceException: Object reference not set to an instance of an object" error. What am I doing wrong?
  19. Archimagus

    Archimagus

    New Member

    Joined:
    Sep 29, 2012
    Messages:
    4
    To the people that can't seem to get this to work. Make sure you scrips file name matches the class name.
  20. dval

    dval

    New Member

    Joined:
    Jul 25, 2012
    Messages:
    7
    Thank you !
  21. DESTRUKTORR

    DESTRUKTORR

    Member

    Joined:
    Jul 4, 2012
    Messages:
    22
    All these seem so overcomplicated. Here, I've taken and optimized it all to work based on what game objects you have selected, rather than having to individually drag an drop every object into an array object in the window... Enjoy.

    Code (csharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using System.Collections;
    4.  
    5. public class ReplaceGameObjects : ScriptableWizard
    6. {
    7.     public GameObject useGameObject;
    8.    
    9.     [MenuItem ("Custom/Replace GameObjects")]  
    10.     static void CreateWizard ()
    11.     {
    12.         ScriptableWizard.DisplayWizard("Replace GameObjects", typeof(ReplaceGameObjects), "Replace");
    13.     }
    14.    
    15.     void OnWizardCreate ()
    16.     {
    17.         foreach (Transform t in Selection.transforms)
    18.         {
    19.             GameObject newObject = (GameObject)EditorUtility.InstantiatePrefab(useGameObject);
    20.             Transform newT = newObject.transform;
    21.             newT.position = t.position;
    22.             newT.rotation = t.rotation;
    23.             newT.localScale = t.localScale;
    24.         }
    25.         foreach (GameObject go in Selection.gameObjects)
    26.         {
    27.             DestroyImmediate(go);
    28.         }
    29.     }
    30. }
    Last edited: Feb 10, 2013
    susted likes this.
  22. raghaaav

    raghaaav

    New Member

    Joined:
    Feb 13, 2013
    Messages:
    1
    Modified so that parent-child relationships are kept intact.

    :)

    Code (csharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using System.Collections;
    4.  
    5. /*
    6.  * http://forum.unity3d.com/threads/24311-Replace-game-object-with-prefab/page2
    7.  * */
    8.  
    9. public class ReplaceGameObjects : ScriptableWizard
    10.  
    11. {
    12.     public GameObject useGameObject;
    13.  
    14.     [MenuItem ("Custom/Replace GameObjects")]  
    15.  
    16.     static void CreateWizard ()
    17.     {
    18.         ScriptableWizard.DisplayWizard("Replace GameObjects", typeof(ReplaceGameObjects), "Replace");
    19.     }
    20.  
    21.     void OnWizardCreate ()
    22.     {
    23.         foreach (Transform t in Selection.transforms)
    24.         {
    25.             GameObject newObject = PrefabUtility.InstantiatePrefab(useGameObject) as GameObject;
    26.             Transform newT = newObject.transform;
    27.  
    28.             newT.position = t.position;
    29.             newT.rotation = t.rotation;
    30.             newT.localScale = t.localScale;
    31.             newT.parent = t.parent;
    32.  
    33.         }
    34.  
    35.         foreach (GameObject go in Selection.gameObjects)
    36.         {
    37.             DestroyImmediate(go);
    38.         }
    39.     }
    40. }
  23. Deepestblue

    Deepestblue

    New Member

    Joined:
    May 11, 2009
    Messages:
    36
    Thanks for this! I kiss the ground on which you walk. :)
  24. BGitlin

    BGitlin

    Member

    Joined:
    Apr 29, 2013
    Messages:
    1
    Awesome update to the script, works great, thanks man
  25. dhun

    dhun

    New Member

    Joined:
    Feb 25, 2013
    Messages:
    1
    Just wanted to say thanks for this, saved me a bunch of time.
  26. MettleRobot

    MettleRobot

    New Member

    Joined:
    Nov 5, 2013
    Messages:
    3
    This is a really useful script. Thanks to everyone who worked on it :)

    There's something I've been looking to to be able to do in Unity for years now. And this script comes the closest so far...

    How hard would it be to automate this process a little more, so it could replace multiple DIFFERENT objects with DIFFERENT prefabs.

    eg. I export an FBX from Max that contains hundreds of modular instanced objects (wall sections, foliage, etc). Import it into Unity and put it in the scene where you can see it still has all the individual objects as children under a game object. And I've already made all the prefab wall sections, foliage objects, etc.

    Could I then run a script that looks at each child object, figures out which of my prefabs it matches. And then go through and replace them all. I could build whole levels in Max this way. It would be amazing!

    The instances from Max have a unique number suffix, but other than that the name of each one could be used to find it's replacement prefab.

    Even better would be if I could put this script on an empty game object in the scene and use it like a manager so it can be told which fbx (or selection of fbx's) from the Assets folder to source and then when you click go it basically runs through the process automatically leaving you with a whole lot of placed prefabs. It could maybe have an option to auto-update if it detects the fbx has been changed.

    I would pay big money for this functionality if I saw it on the Asset Store.
  27. Mutain

    Mutain

    Member

    Joined:
    Jun 1, 2013
    Messages:
    3
    Just added some undo support into your script.

    Code (csharp):
    1. using UnityEditor;
    2. using UnityEngine;
    3.  
    4. /*
    5.  * [url]http://forum.unity3d.com/threads/24311-Replace-game-object-with-prefab/page2[/url]
    6.  * */
    7.  
    8. public class ReplaceGameObjects : ScriptableWizard
    9. {
    10.  
    11.     public GameObject useGameObject;
    12.  
    13.     [MenuItem("Custom/Replace GameObjects")]
    14.  
    15.     static void CreateWizard()
    16.     {
    17.         ScriptableWizard.DisplayWizard("Replace GameObjects", typeof(ReplaceGameObjects), "Replace");
    18.     }
    19.  
    20.     void OnWizardCreate()
    21.     {
    22.         foreach (Transform t in Selection.transforms)
    23.         {
    24.             GameObject newObject = PrefabUtility.InstantiatePrefab(useGameObject) as GameObject;
    25.             Undo.RegisterCreatedObjectUndo(newObject, "created prefab");
    26.             Transform newT = newObject.transform;
    27.  
    28.             newT.position = t.position;
    29.             newT.rotation = t.rotation;
    30.             newT.localScale = t.localScale;
    31.             newT.parent = t.parent;
    32.         }
    33.  
    34.         foreach (GameObject go in Selection.gameObjects)
    35.         {
    36.             Undo.DestroyObjectImmediate(go);
    37.         }
    38.     }
    39. }
  28. a_deadman

    a_deadman

    New Member

    Joined:
    Jan 20, 2014
    Messages:
    1
    I added :

    newObject.name = go.name;

    as well as I needed the names to re-attach them to parameters in one of my scripts needed to know what was what.

    If anyone knows of a way to add the references to the new prefab's please let us know.
  29. AlgorithMan

    AlgorithMan

    New Member

    Joined:
    Feb 13, 2014
    Messages:
    1
    Thank you so much guys! This script is a life saver!
    Here, I also added a second class which replaces objects based on their name instead of based on selection. (I have thousands of instances of the same prefab, all with broken prefab-connection - but they all have the same name, so in a situation like this, this script is more handy)

    Code (csharp):
    1.  
    2. public class BatchReplaceByName : ScriptableWizard
    3. {
    4.     public GameObject NewType;
    5.     public string Name = "";
    6.     public bool MatchCase = false;
    7.    
    8.     [MenuItem("Custom/Batch Replace By Name")]
    9.    
    10.     static void CreateWizard()
    11.     {
    12.         var replaceGameObjects = ScriptableWizard.DisplayWizard <BatchReplaceByName>("Replace GameObjects", "Replace");
    13.     }
    14.    
    15.     void OnWizardCreate()
    16.     {
    17.         GameObject[] allObjects = GameObject.FindObjectsOfType<GameObject>();
    18.         if (!MatchCase)
    19.             Name = Name.ToUpper ();
    20.  
    21.         foreach(GameObject go in allObjects)
    22.         {
    23.             if((MatchCase ? go.name : go.name.ToUpper()) != Name)
    24.                 continue;
    25.  
    26.             GameObject newObject = (GameObject)PrefabUtility.InstantiatePrefab(NewType);
    27.             newObject.transform.parent = go.transform.parent;
    28.             newObject.transform.localPosition = go.transform.localPosition;
    29.             newObject.transform.localRotation = go.transform.localRotation;
    30.             newObject.transform.localScale = go.transform.localScale;
    31.             newObject.name  = go.name;
    32.             UnityEngine.Object.DestroyImmediate(go);
    33.         }
    34.     }
    35. }
    36.  
    Last edited: Mar 8, 2014
  30. MrPhil

    MrPhil

    Member

    Joined:
    Sep 22, 2010
    Messages:
    22
    Don't forget to put the script in a folder called Editor (doesn't matter where, just has to be called "Editor")
  31. mrBeam

    mrBeam

    Member

    Joined:
    Mar 17, 2014
    Messages:
    2
    Hi, I tweaked it in to an Editor Window and now it can handle Scene objects, Prefabs and Objects!
    Enjoy and thanks!

    Code (csharp):
    1.  
    2. using UnityEditor;
    3. using UnityEngine;
    4.  
    5. public class ReplaceSel : EditorWindow
    6. {
    7.     GameObject myObject;
    8.    
    9.     [MenuItem ("Tools/ReplaceSelected %g")]
    10.     public static void ReplaceObjects() {
    11.         EditorWindow.GetWindow(typeof(ReplaceSel));
    12.     }
    13.        
    14.     void OnGUI () {
    15.         GUILayout.Label ("Use Object", EditorStyles.boldLabel);
    16.         myObject = EditorGUILayout.ObjectField(myObject, typeof(GameObject), true) as GameObject;
    17.         if (GUILayout.Button ("Replace Selected")) {
    18.            
    19.             if (myObject != null) {
    20.                 foreach (Transform t in Selection.transforms) {
    21.                     GameObject o = null;
    22.                     o = PrefabUtility.GetPrefabParent(myObject) as GameObject;
    23.                    
    24.                     if (PrefabUtility.GetPrefabType(myObject).ToString() == "PrefabInstance") {
    25.                         o = (GameObject)PrefabUtility.InstantiatePrefab(o);
    26.                         PrefabUtility.SetPropertyModifications(o, PrefabUtility.GetPropertyModifications(myObject));
    27.                     }
    28.                    
    29.                     else if (PrefabUtility.GetPrefabType(myObject).ToString() == "Prefab") {
    30.                         o = (GameObject)PrefabUtility.InstantiatePrefab(myObject);
    31.                     }
    32.                    
    33.                     else {
    34.                         o = Instantiate(myObject) as GameObject;
    35.                     }
    36.                    
    37.                     Undo.RegisterCreatedObjectUndo(o, "created prefab");
    38.                     Transform newT = o.transform;
    39.                     newT.position = t.position;
    40.                     newT.rotation = t.rotation;
    41.                     newT.localScale = t.localScale;
    42.                     newT.parent = t.parent;
    43.                    
    44.                     foreach (GameObject go in Selection.gameObjects) {
    45.                         Undo.DestroyObjectImmediate(go);
    46.                     }
    47.                 }
    48.             }
    49.         }
    50.     }
    51. }
    52.  
    Last edited: Mar 19, 2014
  32. Elecman

    Elecman

    Member

    Joined:
    May 5, 2011
    Messages:
    516
    Nice script, but it has a bug which makes it unusable. This code should be place outside of the foreach:
    Code (csharp):
    1.  
    2. foreach (GameObject go in Selection.gameObjects) {
    3.  
    4.     Undo.DestroyObjectImmediate(go);
    5. }
    6.  
    So it becomes this:
    Code (csharp):
    1.  
    2. using UnityEditor;
    3. using UnityEngine;
    4.  
    5. public class ReplaceSel : EditorWindow
    6. {
    7.     GameObject myObject;
    8.     [MenuItem ("Tools/ReplaceSelected %g")]
    9.  
    10.     public static void ReplaceObjects() {
    11.  
    12.         EditorWindow.GetWindow(typeof(ReplaceSel));
    13.     }        
    14.  
    15.     void OnGUI () {
    16.  
    17.         GUILayout.Label ("Use Object", EditorStyles.boldLabel);
    18.  
    19.         myObject = EditorGUILayout.ObjectField(myObject, typeof(GameObject), true) as GameObject;
    20.  
    21.         if (GUILayout.Button ("Replace Selected")) {            
    22.  
    23.             if (myObject != null) {
    24.  
    25.                 foreach (Transform t in Selection.transforms) {
    26.  
    27.                     GameObject o = null;
    28.                     o = PrefabUtility.GetPrefabParent(myObject) as GameObject;                    
    29.  
    30.                     if (PrefabUtility.GetPrefabType(myObject).ToString() == "PrefabInstance") {
    31.  
    32.                         o = (GameObject)PrefabUtility.InstantiatePrefab(o);
    33.                         PrefabUtility.SetPropertyModifications(o, PrefabUtility.GetPropertyModifications(myObject));
    34.                     }                    
    35.  
    36.                     else if (PrefabUtility.GetPrefabType(myObject).ToString() == "Prefab") {
    37.  
    38.                         o = (GameObject)PrefabUtility.InstantiatePrefab(myObject);
    39.                     }                    
    40.  
    41.                     else {
    42.  
    43.                         o = Instantiate(myObject) as GameObject;
    44.                     }                    
    45.  
    46.                     Undo.RegisterCreatedObjectUndo(o, "created prefab");
    47.  
    48.                     Transform newT = o.transform;
    49.  
    50.                     if(t != null){                     
    51.  
    52.                         newT.position = t.position;
    53.                         newT.rotation = t.rotation;
    54.                         newT.localScale = t.localScale;
    55.                         newT.parent = t.parent;  
    56.                     }
    57.                 }
    58.  
    59.                 foreach (GameObject go in Selection.gameObjects) {
    60.  
    61.                     Undo.DestroyObjectImmediate(go);
    62.                 }
    63.             }
    64.         }
    65.     }
    66. }
    67.  
    By the way, there is a wiki for this (similar) script here:
    http://wiki.unity3d.com/index.php/ReplaceSelection
    Last edited: May 7, 2014
  33. Meceka

    Meceka

    Member

    Joined:
    Dec 23, 2013
    Messages:
    133
    This is great, I wish I could see this script earlier. Thank you.
  34. Christopher Simon

    Christopher Simon

    Member

    Joined:
    Jun 28, 2014
    Messages:
    4
    Thank you guys so much! I'm loving this awesome script!