- Home /
How do I render a prefab without any scripts/components running?
We have a number of prefabs that we instantiate as needed, each of which contain several scripts that automatically initialize them, send messages, register in lists, do fun stuff, etc.
However, I would like to render an "empty" copy of the prefab (i.e. just draw it without it doing any arbitrary stuff in the background), and I would like to know the best, safest, most reliable way to do this.
My first thought was to try to pull out all the meshes/renderers/animation components from the prefab, dynamically 'build' another, and use that, but I don't think there is any way to access the internals of the prefab without instantiating it (please correct me if that is wrong).
Assuming that is true, then I would need to instantiate the prefab. Is it possible to Instantiate() the prefab without running any of the code in the scripts, including their Awake() methods?
Can you make a new prefab which is a "base prefab" that is the empty copy, and have that prefab included in the more complex one? Then changes to the base would still propagate to the scripted one, but you have more options about which one to instantiate. (Unless I'm remembering wrong, and you can't composite prefabs).
It's just an issue of quantity really; we have hundreds of prefabs so I would like a programmatic solution which does not require a significant alteration to the content pipeline.
I'd just create a second prefab and add a postfix _empty to it. This way you can instantiate it like any other prefab. Or is this not an option for some reason?
Really just a scaling issue -- we have hundreds of prefabs, and more on the way, so doubling the asset count and the maintenance required to keep them in sync just isn't practical.
What if ins$$anonymous$$d of doing this at runtime you make an in-editor tool that preprocesses all of your prefabs and creates _empty versions? You could even write it in such a way that it maintains sync between the main and _empty prefabs. Probably. :)
Answer by anomalous_underdog · Nov 17, 2010 at 12:12 AM
Use SetActiveRecursively(false) on the instantiated game object so it won't do any script processing.
Answer by Bunny83 · Dec 28, 2010 at 06:05 AM
The problem is that if you instantiate a prefab right after the Instantiate() call Awake is called before you can do anything else. It's almost like the constructor. If that's not a big problem you can instantiate your prefab anddeactivate or remove the components you don't need / want like mentioned above. There's a nice way to remove or deactivate only the scripts of an GameObject:
MonoBehaviour[] Scripts = GetComponentsInChildren<MonoBehaviour>(); foreach (MonoBehaviour MB in Scripts) { [...]
}
If the Awake would get you in trouble my approach would be to write an editor script that creates those preview-prefabs in the editor. Editorscripts are so powerful, half of my life is running in the Unityeditor. It's almost like you are in "The Matrix" :D
Answer by Ashkan_gc · Dec 31, 2009 at 05:21 PM
first of all, you can easily change the components of prefabs before their instantiation. you should have a reference to them in your script. if you have that reference you can just use the GetComponent function and get it's components and do any other thing that you do with a normal gameobject. even you can change the transform but it's not in your scene and it will not render in any position. i don't know much about the implementation because the documentation says nothing about the engine internals. you can disable your scripts easily. let's assume that you have a prefab reference called "o" that is a GameObject. there is a script attached to it called "s", to disable this just right a code like this.
o.GetComponent<s>().enabled=false;
this is a C# code and the method is generic and can not be used on iphone. you should use the method with typeof or as keyword in iphone.
about drawing a mesh you can do different things. 1 if you have unity pro just use the graphics class methods to draw meshes. it's the fastest and most lightweight way to draw a mesh in unity. 2 you can create another prefab with new requirements and don't add script components and other components that you don't need and instantiate that prefab instead of the original one.
The Graphics.Draw$$anonymous$$esh stuff is in the right direction, but it requires a $$anonymous$$esh, which brings me back to needing to get at the stuff inside the prefab again :)
what about disabling prefab components and instantiating it? then you can enable components of the prefab again.
As a supplament to Ashkan's answer.
If you want to make sure things are unchanged after you have done your stuff and you don't want to have to manually clean everything up, you can use RAII (Resource Acquisition Is Initialization) design pattern:
The answer near the bottom by '280Z28' shows an example of how to do RAII in C#. It is a good way to change the state of the program/object temporarily. It also helps keep all the state modification code together making it more maintainable.
Your answer
Follow this Question
Related Questions
The name 'Joystick' does not denote a valid type ('not found') 2 Answers
Acces a component on an instantiated object 1 Answer
Water splash issues... 2 Answers
Can we do this in Unity 3d? 1 Answer