For our next game, I have been experimenting with an idea to have XML elements - loaded at game startup - dictate which Unity components get attached to instantiated game objects during initialization. I also wanted us to have some level of control in the Unity inspector over which scripts are actually used for the components.
Consider the following code:
gameObject.AddComponent<MyAwesomeScript>();
This adds MyAwesomeScript as a component on the current gameObject. Simple and straightforward (and probably how you would add components in code 95% of the time).
But what if you didn't know MyAwesomeScript at compile time? What if the type of component that's actually added isn't even known until you call AddComponent()?
In comes MonoScript to the rescue! The MonoScript class is a Unity C# class that defines a type of script, not an actual instantiated script object.
As an example, imagine the above component that's added is actually configurable by the inspector in Unity:
![](https://static.wixstatic.com/media/3cd7b4_6789c1c2e1474851b66417039e16860d~mv2.png/v1/fill/w_467,h_23,al_c,q_85,enc_auto/3cd7b4_6789c1c2e1474851b66417039e16860d~mv2.png)
Then when AddComponent() is called, it would use whatever script was set in that field (MyAwesomeScript in the example above).
Later if some designer or engineer wants to experiment with a different component script called "MyOTHERAwesomeScript", they could just change that value in the inspector:
![](https://static.wixstatic.com/media/3cd7b4_568b3eb1135e42e980a9d207370137e1~mv2.png/v1/fill/w_472,h_21,al_c,q_85,enc_auto/3cd7b4_568b3eb1135e42e980a9d207370137e1~mv2.png)
and it would *just work* without having to modify the code. Of course if any other scripts are referencing functions in "MyAwesomeScript", you will need to ensure that "MyOTHERAwesomeScript" implements the same functions! Using interfaces will help out a lot here, but I will leave interface discussion until a later tech tip :-)
But the problem is how do we actually reference that script type in code when calling AddComponent()? In the code snippet above where I first called AddComponent(), we had to know the type was "MyAwesomeScript".
This is where MonoScript comes in. The above inspector items are actually coded as:
public UnityEditor.MonoScript ScriptToAddAsComponent;
MonoScript is essentially an object representing a class type, not the class itself.
When we call AddComponent(), we can do the following:
// Assume ScriptToAddAsComponent is the name of the inspector field.
System.Type classType = ScriptToAddAsComponent.GetClass();
gameObject.AddComponent(classType);
And voila! Whichever script is set in the inspector gets added as a component. The System.Type is a C# thing, and fortunately Unity has an AddComponent() overload which accepts a System.Type (see here for the Unity documentation on AddComponent() - note I use the full "System.Type" qualification in my code example, but if you just use the System namespace in your script then you don't need to use "System." before "Type").
Okay, thought that was interesting enough to share!
Follow @AngryGoatGames on Twitter! We post useful game dev articles as we come across them!
![](https://static.wixstatic.com/media/97ce3d_09451950a8524e20addf310756a1b6d4~mv2.jpg/v1/fill/w_980,h_980,al_c,q_85,usm_0.66_1.00_0.01,enc_auto/97ce3d_09451950a8524e20addf310756a1b6d4~mv2.jpg)
Comentarios