- Home /
How to find a prefab via script at RunTime?
Suppose in my game I will Instantiate some prefabs. And every time I instatiate a Prefab it will be random and will destroyed after few seconds. That means I cannot assign my prefabVariable from the editor
// my prefabVariable that i want to assign
// different prefabs at different time via script
// as opposed to drag-dropping GameObjects in
// the editor
var variableForPrefab :GameObject;
function Start()
{
// for finding a game object we could do
// variableForPrefab = GameObject.Find("GameObjectName");
// if we want to find prefab like this, how can I do this??
}
PS: 1. how to do so randomly is NOT my concern 2. I want to know how to find a prefab via script at Run Time
Actually, I'm kind of wondering the same thing. I'm not sure if it's possible to directly instantiate a Prefab because I'm not sure if Unity includes prefabs in the build (if they're not being used as a reference). But if there is a way, I'd like to know as well.
But maybe you could put all the possible ones in an array of GameObjects, and then pick a random index and instantiate that one?
Edit: I see your edit, but why won't our solution work? Are there just too many? You will be able to do exactly what you're apparently wanting to do with an array of GameObjects.
Well... at least it's a backup plan, because I don't think you can do what you're wanting to do.
Answer by Bunny83 · Mar 27, 2014 at 12:36 AM
An alternative solution to the one Leuthil mentioned is to put your prefabs into a special folder called Resources. Once they in there you can use Resources.Load to get the reference to the desired prefab. The path is relative to the resources folder. So imagine you have this setup:
"/Assets/resources/prefabs/prefab1.prefab"
You could load that prefab by using:
// UnityScript
variableForPrefab = Resources.Load("prefabs/prefab1", GameObject) as GameObject;
// C#
variableForPrefab = (GameObject)Resources.Load("prefabs/prefab1", typeof(GameObject));
While this works and seems to be quite useful it has some drawbacks:
It's of course slower than linking the prefabs in the inspector since the method has to search at runtime for the resource.
Everything inside the Resources folders are included in the build, no matter if you actually use it somewhere. Unity can't determine what is needed and what isn't.
So Leuthil's solution is the recommended one.
damn! your answer is even better than the documentation! :D I have read the documentation for Resource.Load() but didn't know about creating the resource folder. You explained this so clearly, I was about to ask the pros and cons of this method and I noticed you included this too! ^__^
Well, the scripting reference is about thesignature of methods and a short description of what it does. The **manual** is where you get conceptional information and the Resource folders are explained quite in detail i think ;)
Thanks for that, totally didn't think of that approach! (Though I personally wouldn't use resources for that).
Just curious @Bunny83 but when would this ever have an advantage for loading prefabs? Or is this function mainly used for other things like loading Textures/Audio?
As an answer to Leuthil question about when this would ever be an advantage for loading prefabs, there's one really big example : World $$anonymous$$anagement.
Let's says that your game is made out of chunks that get modified because of whatever might modify them... be it events you created that destroy a part of the environment or simply out of the fact that the player might be able to slightly modify the environment. Of course, you could go with the Voxel-based approach and record every voxels change through scripts, but what if you aim at something lighter (for mobile as example) and that you don't plan to have $$anonymous$$ute-made changes to your environment? What if all you want to do is switch prefab A to B? Well, if you only change a couple in the world at a time (big chunk), you could store the prefab in the Inspector through some kind of public accessible array.
But then what if your world is made out of thousands of chunk? Here comes the magic of Ressource.Load! By using a clear and consistent na$$anonymous$$g convention for your world chunk as prefabs in a specific folder, you can simply use Ressource.Load to select the exact prefab you need out of the thousands that might be around in that folder.
To give you an actual example, I'm currently working on a mobile game which allows the player to absorb parts of the world to change its characters' composition. The player can only absorb a part once per day unless he or she decide to "Deep Sleep" which reset the world at the expense of a major change (drop) in the player's composition. The world I'm making is 3000 units squared in size and each world chunk is 1 unit square. That makes the world into a bunch of 9,000,000 chunks. Obviously, I'm using some big cheat method to manage the whole thing so that I don't get an huge amount of materials (world-space based shaders that apply the texture I need based on the position in the world and so on.) Still, each part could be "absorbable" and, if that's the case, it could be visually absorbed or not. So you got a big world made of 9 millions chunk and some of those chunks could be 1 of 2 things. The game has a Bird-view, meaning you don't see far away. That save a lot in terms of rendered chunks at once.
Ressource.Load makes it rather simple to manage what prefab has to be in the scene. All I got to do is convert the player position into about 25 specific integrers that act as the IDs of the chunks that has to be instantiated around the player. Let's say the player is on the chunk 1246x1234. It's easy to setup the na$$anonymous$$g convention as "WorldChunk_" + X.tostring + "x" + Y.tostring(); to get a specific chunk out of the 9 millions in a folder. (Obviously, I'll use a multi-layered Chunk system as 9$$anonymous$$ is a bit too big, but I just want to give an example of how it can be useful. I mostly will cut it into 9 Chunk of 10x10 smaller chunk containing 100x100 even smaller chunks each )
Well, you can use it for anything you can imagine ;) As far as i remember we had someone who had around 2000 different models in his project and based on some kind of database he wanted to load certain models by name. Adding all those models to an array and then figure out which index is which was way to complicated.
That's why i said in most cases the array approach is the better one. "$$anonymous$$ost" doesn't mean all ;)
ps: even when you have 2000 assets you could still use an array (keep in $$anonymous$$d you can drag them all together onto the array), then at runtime you create a dictionary and matching the prefabs name with the prefab itself. It's of course a bit more complicated and it could happen that you accidentally add the same asset twice to the array but it would also work. The maintainability suffers a bit and if you want to sort your assets it's getting more complicated ;)
With the resource folder you can have subfolders so you can organise your assets in a directory tree. It's just a bit simpler.
Answer by Leuthil · Mar 26, 2014 at 08:24 PM
You can create an array and put each prefab you want to randomly choose from in that array. Then you will be able to drag-and-drop all of the prefabs into that array.
I do this too, but does anyone know how to automatically update this in the editor? Every-time I add a new prefab, I have to delete the list, click "All Prefabs" and drag it into the list. It takes 15 seconds each time I do it, but it's still mildly tedious.
An editor script/button to auto-update the list to all the prefabs in the Assets folder would make it more maintainable.
I think a farily easy solution would be to have a public gameobject 'prefabToAdd', and after you place it there, you have an Conetxt menu function that you can trigger that adds that prefab to the list
I'll take a look into Context Menu Functions. So it's possible to add and remove (automatically) prefabs in the Asset folder?
Hmm, or maybe it might just be best to update this manually if I only need to do this once every few days? It takes only 15 seconds anyway.
Create a list from the folder by using: Resources.LoadAll ("/Prefab/BlockPrefabs") as GameObject[];
Do what you want to do with each prefab by Iterating with a loop through it.
Thanks, I got it working through the combination of:
Button on Inspector: https://learn.unity.com/tutorial/editor-scripting#5c7f8528edbc2a002053b5f8
Load prefabs outside of Resource directory: https://stackoverflow.com/a/67670629
After that, decided to just load the prefabs once at the start of run-time.
Your answer

Follow this Question
Related Questions
Communicating between objects in the same prefab? 1 Answer
Random Script Failure 1 Answer
assign different values to prefabs on instantiation 2 Answers
Accessing a game object from a script? 1 Answer
making prefabs at runtime? 2 Answers