- Home /
Swapping one model for a prefab
Heya guys,
I'm currently working on a architectural visualization of a huge building. I was painstakingly making every door operable manually until someone pointed me in the direction of prefabs. Now My understanding is limited so bare with me.
So I have made a prefab which is operable (open/close) and it works fine. It is the exact same mesh as all the other doors in my level. (It is in fact the same model) in every way except for the attached door script and box collider (inside an empty game object renamed to hinge). I want to swap all my doors (placeholders) for the prefab. this isn't in game just in the building of the model/level.
Is this at all possible? swap one "item" for another?
any help as always is greatly appreciated.
Chris
Answer by kalvinlyle · Apr 04, 2012 at 09:59 AM
Here's a modified script that I use to replace prefabs in scenes by name. It works base don selection within the editor, so just select all your objects and and hit CMD+R. It will look through your scene and find prefabs that match the names of the objects in your scene. you can modify the code to create substitutions.
Put this in your Editor folder (requires Unity Pro)
If anyone has any idea how to make this script more flexible please let me know.
@MenuItem ("Tools/Replace with Prefab %r")
static function Replace() {
var transforms = Selection.transforms;
for (var i : int = 0; i < transforms.Length; i++) {
var localPath : String;
var newObject : GameObject;
var objectName : String = transforms[i].gameObject.name;
//Swap out prefabs to new ones based on which ones are obsolete
if(transforms[i].gameObject.name == "Heart")
objectName = "C_Gem";
else if (transforms[i].gameObject.name == "Star")
objectName = "C_Coin";
else if (transforms[i].gameObject.name == "Golden_Banana")
objectName = "C_Banana";
else if (transforms[i].gameObject.name == "Banana_Bunch")
objectName = "C_Boost";
else if (transforms[i].gameObject.name == "Propeller_Hat")
objectName = "C_Hat";
else if (transforms[i].gameObject.name == "Wings")
objectName = "C_Wings";
else if (transforms[i].gameObject.name == "P_Steel")
objectName = "P_Pipe";
//Search through each directory in the prefabs folder for the right object
localPath = "Assets/Prefabs/" + objectName + ".prefab";
if(AssetDatabase.LoadAssetAtPath(localPath, Object))
newObject = EditorUtility.InstantiatePrefab(AssetDatabase.LoadAssetAtPath(localPath, Object)) as GameObject;
localPath = "Assets/Prefabs/Backgrounds/" + objectName + ".prefab";
if(AssetDatabase.LoadAssetAtPath(localPath, Object))
newObject = EditorUtility.InstantiatePrefab(AssetDatabase.LoadAssetAtPath(localPath, Object)) as GameObject;
localPath = "Assets/Prefabs/Cameras/" + objectName + ".prefab";
if(AssetDatabase.LoadAssetAtPath(localPath, Object))
newObject = EditorUtility.InstantiatePrefab(AssetDatabase.LoadAssetAtPath(localPath, Object)) as GameObject;
localPath = "Assets/Prefabs/Characters/" + objectName + ".prefab";
if(AssetDatabase.LoadAssetAtPath(localPath, Object))
newObject = EditorUtility.InstantiatePrefab(AssetDatabase.LoadAssetAtPath(localPath, Object)) as GameObject;
localPath = "Assets/Prefabs/Collectibles/" + objectName + ".prefab";
if(AssetDatabase.LoadAssetAtPath(localPath, Object))
newObject = EditorUtility.InstantiatePrefab(AssetDatabase.LoadAssetAtPath(localPath, Object)) as GameObject;
localPath = "Assets/Prefabs/Effects/" + objectName + ".prefab";
if(AssetDatabase.LoadAssetAtPath(localPath, Object))
newObject = EditorUtility.InstantiatePrefab(AssetDatabase.LoadAssetAtPath(localPath, Object)) as GameObject;
localPath = "Assets/Prefabs/Menus/" + objectName + ".prefab";
if(AssetDatabase.LoadAssetAtPath(localPath, Object))
newObject = EditorUtility.InstantiatePrefab(AssetDatabase.LoadAssetAtPath(localPath, Object)) as GameObject;
localPath = "Assets/Prefabs/Obstacles/" + objectName + ".prefab";
if(AssetDatabase.LoadAssetAtPath(localPath, Object))
newObject = EditorUtility.InstantiatePrefab(AssetDatabase.LoadAssetAtPath(localPath, Object)) as GameObject;
localPath = "Assets/Prefabs/Platforms/" + objectName + ".prefab";
if(AssetDatabase.LoadAssetAtPath(localPath, Object))
newObject = EditorUtility.InstantiatePrefab(AssetDatabase.LoadAssetAtPath(localPath, Object)) as GameObject;
localPath = "Assets/Prefabs/Story/" + objectName + ".prefab";
if(AssetDatabase.LoadAssetAtPath(localPath, Object))
newObject = EditorUtility.InstantiatePrefab(AssetDatabase.LoadAssetAtPath(localPath, Object)) as GameObject;
localPath = "Assets/Prefabs/TriggerVolumes/" + objectName + ".prefab";
if(AssetDatabase.LoadAssetAtPath(localPath, Object))
newObject = EditorUtility.InstantiatePrefab(AssetDatabase.LoadAssetAtPath(localPath, Object)) as GameObject;
localPath = "Assets/Prefabs/Tutorial/" + objectName + ".prefab";
if(AssetDatabase.LoadAssetAtPath(localPath, Object))
newObject = EditorUtility.InstantiatePrefab(AssetDatabase.LoadAssetAtPath(localPath, Object)) as GameObject;
//Replace the current object with the prefab (sets position, rotation and scale)
if(newObject){
newObject.transform.position = transforms[i].position;
newObject.transform.localRotation = transforms[i].localRotation;
newObject.transform.localScale = transforms[i].localScale;
DestroyImmediate(transforms[i].gameObject);
}else{
Debug.Log(transforms[i].gameObject.name + " not found in Prefab Library");
}
}
}
Hey man, I appreciate the help but maybe I should have mentioned that I'm using windows :( I'll google the equivalent of "C$$anonymous$$D+R" and give it a try. The existing "models" aren't prefabs though. Will that make a difference?
Thanks alot.
This doesn't require Unity pro. No pro feature has been used in this editor script.
C$$anonymous$$D+R is the hotkey defined in the $$anonymous$$enuItem (`%r`) %
means C$$anonymous$$D($$anonymous$$ac) or CRTL(Win). You can use any hotkey you like as long as it isn't used for something else. See $$anonymous$$enuItem for more information.
Anyway this script isn't very robust. If there are two prefabs with the same name but in different folders it will instantiate both but only use the last one.
It doesn't matter if the models are prefabs or not, the script just replaces the objects by name. I used it to replace broken prefabs and turn them back into prefabs. Bunny is right that the script is kinda crap but it gets the job done. I didn't run into the problem he's pointed out with the multiple instances but not that he mentions it, it's kind of obvious that would happen :S
Answer by morphus1 · Apr 05, 2012 at 03:38 PM
Hey guys, I'm not getting this to work :( Bare with as I'm just getting to grips with this whole scripting thing.
You have the line/s
//Swap out prefabs to new ones based on which ones are obsolete if(transforms[i].gameObject.name == "Heart") objectName = "C_Gem";
So I swap out "Heart" with the existing models name and where it says "C_Gem" I put the name of my prefab in right? Then I select the existing models in game and hit CTRL+R and it should swap out all the existing models to the prefab stated in the string?
If so, It's not happening for me.
Your answer
Follow this Question
Related Questions
How to drop my held weapon after picking one up? 1 Answer
Why are all clones moving when one should be moving 0 Answers
Swapping gameobjects 2 Answers
How to swap 2 gameobjects after 2 click! 4 Answers