loading prefab from path
I am working on a 2d game with very detailed modding support (which I know is silly for a unity game, but I don't care), and I am loading some things from JSON files, such as the size of the map, and what doors lead where. Because of this, I can use one variable, the map to load, to load literally any map with a JSON file attached... except the actual tiles in the map, which are in a prefab. I don't want to have to make hundreds of public GameObject variables for every map prefab, so is there a way I can just load one from a path?
Example: instead of:
public GameObject ForestPath2; Instantiate(ForestPath2, new Vector3(0, 0, 0), Quaternion.identity);
do:
String mapName = ForestPath2; Insantiate("Assets/Maps/prefabs/"+mapName ,new Vector3(0, 0, 0), Quaternion.identity);
Answer by Vicarian · Jul 01, 2017 at 01:03 AM
From your example, it seems like you need to load up a dynamic type at runtime based on certain criteria, so you'll likely need to look into Reflection, where you can perform the AddComponent generic call by supplying a type determined at runtime. It would be disingenuous for me to regurgitate Reflection knowledge here, as it's a powerful, and quite complex tool. Some study will definitely be required, and a good starting point is the MSDN.
Or, you could simply rethink your design and create a Weather superclass that handles the loading of the different types of weather. Either way would work, though the latter would require far less code.
I'll look into whether a superclass would work, thanks! I still get an error for the first issue (prefabs), though.
I don't know if a superclass would work because the whole point of this is that most stuff can be modified by a text editor and an idiot - If you want to make fire rain, make a class for hot raindrops, and a class to spawn them and clouds, and call it through a trigger like a mission. A superclass would still need to have its subclasses called... that or I'm way too tired to be program$$anonymous$$g...
For that, the Assets folder is assumed, and you have to place things in a Resources folder under the Assets folder, which also is assumed. So, to instantiate a prefab, you'll have
Type t = Instantiate(Resources.Load<Type>("pathWithout$$anonymous$$ingSlash"));
which works as long as the prefab has a Component of the type Type
attached to it. Otherwise you can simply do GameObject
for the type.
Say I have a folder called Prefabs in my Resources folder, and I want to load the SomeCoolPrefab prefab, and it's just a vanilla Transform with some tediously configured other components and the like which are built-in to Unity. I'd use GameObject, and the call would be:
GameObject someCoolPrefab = Resources.Load("Prefabs/SomeCoolPrefab");
GameObject someCoolPrefabInstance = Instantiate(someCoolPrefab);
You can do the above all on one line by using the form I used previously. Otherwise, if you want to instantiate a lot of the prefabs, you can do the above to hold the prefab in memory, and make as many copies of it you need. Alternatively, if you know the type of a component on the prefab, you can use that type, using the generic form I used first, and the path would be similar.
Thanks! The map loads, and since I can load objects, I can just create one that has all the scripts for each weather condition.
Edit: upon creating a weather object, I've come across a problem - it can't create other objects?
Second edit: Never $$anonymous$$d, I'm an idiot and constantly destroyed and replaced the object, removing its timer.
Answer by zan49er · Jun 30, 2017 at 09:50 PM
I tried this:
Instantiate(Resources.Load("Assets/Maps/prefabs/" + mapName + ".prefab"), new Vector3(0, 0, 0), Quaternion.identity);
but it gives an error which is that the object I'm trying to instantiate is null.
I also need to load a script, but this:
gameObject.AddComponent("Assets/Scripts/weather/" + currentweather + "/" + currentweather + ".cs");
is depreciated, so I tried this:
weatherClass = new type("Assets/Scripts/weather/" + currentweather + "/" + currentweather + ".cs");
gameObject.AddComponent<weatherClass>();
but I can't create a type like that.