After extensive experiment I was able get this. This covers all the Unity components too. Just made it an extension method to make life easier.
public static class ExtensionMethod
{
public static Component AddComponentExt(this GameObject obj, string scriptName)
{
Component cmpnt = null;
for (int i = 0; i < 10; i++)
{
//If call is null, make another call
cmpnt = _AddComponentExt(obj, scriptName, i);
//Exit if we are successful
if (cmpnt != null)
{
break;
}
}
//If still null then let user know an exception
if (cmpnt == null)
{
Debug.LogError("Failed to Add Component");
return null;
}
return cmpnt;
}
private static Component _AddComponentExt(GameObject obj, string className, int trials)
{
//Any script created by user(you)
const string userMadeScript = "Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null";
//Any script/component that comes with Unity such as "Rigidbody"
const string builtInScript = "UnityEngine, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null";
//Any script/component that comes with Unity such as "Image"
const string builtInScriptUI = "UnityEngine.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
//Any script/component that comes with Unity such as "Networking"
const string builtInScriptNetwork = "UnityEngine.Networking, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
//Any script/component that comes with Unity such as "AnalyticsTracker"
const string builtInScriptAnalytics = "UnityEngine.Analytics, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null";
//Any script/component that comes with Unity such as "AnalyticsTracker"
const string builtInScriptHoloLens = "UnityEngine.HoloLens, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null";
Assembly asm = null;
try
{
//Decide if to get user script or built-in component
switch (trials)
{
case 0:
asm = Assembly.Load(userMadeScript);
break;
case 1:
//Get UnityEngine.Component Typical component format
className = "UnityEngine." + className;
asm = Assembly.Load(builtInScript);
break;
case 2:
//Get UnityEngine.Component UI format
className = "UnityEngine.UI." + className;
asm = Assembly.Load(builtInScriptUI);
break;
case 3:
//Get UnityEngine.Component Video format
className = "UnityEngine.Video." + className;
asm = Assembly.Load(builtInScript);
break;
case 4:
//Get UnityEngine.Component Networking format
className = "UnityEngine.Networking." + className;
asm = Assembly.Load(builtInScriptNetwork);
break;
case 5:
//Get UnityEngine.Component Analytics format
className = "UnityEngine.Analytics." + className;
asm = Assembly.Load(builtInScriptAnalytics);
break;
case 6:
//Get UnityEngine.Component EventSystems format
className = "UnityEngine.EventSystems." + className;
asm = Assembly.Load(builtInScriptUI);
break;
case 7:
//Get UnityEngine.Component Audio format
className = "UnityEngine.Audio." + className;
asm = Assembly.Load(builtInScriptHoloLens);
break;
case 8:
//Get UnityEngine.Component SpatialMapping format
className = "UnityEngine.VR.WSA." + className;
asm = Assembly.Load(builtInScriptHoloLens);
break;
case 9:
//Get UnityEngine.Component AI format
className = "UnityEngine.AI." + className;
asm = Assembly.Load(builtInScript);
break;
}
}
catch (Exception e)
{
//Debug.Log("Failed to Load Assembly" + e.Message);
}
//Return if Assembly is null
if (asm == null)
{
return null;
}
//Get type then return if it is null
Type type = asm.GetType(className);
if (type == null)
return null;
//Finally Add component since nothing is null
Component cmpnt = obj.AddComponent(type);
return cmpnt;
}
}
Usage:
gameObject.AddComponentExt("YourScriptOrComponentName");
It is important to understand how I did it so that you can add support for new components in any future Unity updates.
For any script created by users:
1.Find out what needs to be in the ??? in the Assembly.Load function.
Assembly asm = Assembly.Load("???");
You can do that by putting this in your script:
Debug.Log("Info: " + this.GetType().Assembly);
I got: Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
We should now replace ??? with that.
Assembly asm = Assembly.Load("Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
2.Find out what needs to be in the ??? in the asm.GetType function.
Assembly asm = Assembly.Load("Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
Type type = asm.GetType(???);
In this case, it is simply the name of the script you want to add to the GameObject.
Let's say that your script name is NathanScript:
Assembly asm = Assembly.Load("Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
Type type = asm.GetType("NathanScript");
gameObject.AddComponent(type);
For Unity built in scripts/components scripts not created by users:
Example of this is the Rigidbody, Linerenderer, Image components. Just any component not created by the user.
1.Find out what needs to be in the ??? in the Assembly.Load function.
Assembly asm = Assembly.Load("???");
You can do that by putting this in your script:
ParticleSystem pt = gameObject.AddComponent<ParticleSystem>();
Debug.Log("Info11: " + pt.GetType().Assembly);
I got: UnityEngine, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
We should now replace ??? with that.
Assembly asm = Assembly.Load("UnityEngine, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
2.Find out what needs to be in the ??? in the asm.GetType function.
Assembly asm = Assembly.Load("UnityEngine, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
Type type = asm.GetType(???);
You can do that by putting this in your script:
ParticleSystem pt = gameObject.AddComponent<ParticleSystem>();
Debug.Log("Info: " + pt.GetType());
I got: UnityEngine.ParticleSystem
Remember that ParticleSystem is used as an example here. So the final string that will go to the asm.GetType function will be calculated like this:
string typeString = "UnityEngine." + componentName;
Let's say that the Component you want to add is LineRenderer:
Assembly asm = Assembly.Load("UnityEngine, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
string typeString = "UnityEngine." + "LineRenderer";
Type type = asm.GetType(typeString);
gameObject.AddComponent(type);
Putting it together in an extension method:
As you can see, adding scripts you created and the script/components that comes with Unity requires totally different process. You can fix this by checking if the type if null. If the type is null, perform the other step. If the other step is null too then the script simply does not exit.
assembly.GetTypes().Any(t => t.Name == scriptname);