- Home /
Add all scripts in a folder to a GameObject at runtime?
Hi all,
I have a Resource folder which contains some scripts. I want to, from another script's Start() function, loop through all the scripts in a specific folder and add each one of those scripts to a GameObject as a new component. How can I accomplish this?
I'm able to get each script as an Object via Resources.LoadAll(), and from there I can get the name of the script as a string, but not a type. Type.GetType(scriptName) doesn't work because it requires the assembly name, AddComponent(scriptName) is deprecated since Unity 5 and Resources.LoadAll() returns an array of Objects and I can't cast them to the appropriate script types to be added to the GameObject.
If anyone has any ideas I'd really appreciate the input! Thanks
Answer by ShadyProductions · Feb 06, 2018 at 09:36 PM
To answer the main question, and @OrnelasOne's question and for any other people who might be looking for the answer.. I figured out how to do it:
using UnityEditor;
using UnityEngine;
public class ScriptLoader : MonoBehaviour {
void Start () {
// Cast to MonoScript object
var scripts = Resources.LoadAll<MonoScript>("Scripts");
var go = new GameObject("blabla");
foreach (var script in scripts)
{
// GetClass method returns the type of the script
go.AddComponent(script.GetClass());
}
}
}
Answer by Kestu · 2 days ago
I found another way to do it. This way you dont have to attach it as a script to a gameobject. It does require you attach a specific interface to all scripts you want to run. It also fetches scripts from the entire project and not just in a single folder.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Reflection;
using System;
using System.Linq;
public class GetAllScriptsExample : MonoBehaviour
{
//attach this script to a gameobject somewhere so the awake can run
//it gets every single script in the project with "IItemInterface" on it and runs "GetItem();" on all of them.
//This loads scr_Item objects into a static dictionary. You could make it do anything though.
public static IDictionary<string, scr_Item> itemDict { get; private set; } = new Dictionary<string, scr_Item>();
void Awake()
{
Assembly assembly = Assembly.GetAssembly(typeof(IItemInterface));
var allItems = assembly.GetTypes()
.Where(t => typeof(IItemInterface).IsAssignableFrom(t) && t.IsAbstract == false);
foreach (System.Type script in allItems)
{
IItemInterface myRecipeInterface = Activator.CreateInstance(script) as IItemInterface;
scr_Item item = myRecipeInterface.GetItem();
if (itemDict.ContainsKey(item.name))
{
//do nothing
Debug.Log("item problem detected: duplicate item " + item.name);
}
else
{
itemDict.Add(item.name, item);
}
}
}
}
Then here is an example of an scr_Item that this script can fetch. Notice the IItemInterface on there.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class scr_DistilledWaterItem : IItemInterface
{
public scr_Item GetItem()
{
scr_Item thisItem = new scr_Item();
thisItem.name = "Distilled Water";
thisItem.description = "Water with all mineral impurities removed. An even stronger solvent.";
thisItem.maxStackSize = 100;
thisItem.color = new Color32(255, 255, 225, 255);
thisItem.intensity = 0;
Sprite distilledWaterSprite = Resources.Load<Sprite>("Sprites/Icons/Fluids/distilledWater");
thisItem.sprite = distilledWaterSprite;
return thisItem;
}
}
And then finally the interface itself:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public interface IItemInterface
{
/// <summary>
/// Use this to build items at runtime.
/// </summary>
scr_Item GetItem();
}
I got this code from this video: https://youtu.be/nqAHJmpWLBg