经过广泛的实验,我得到了这个。这也涵盖了所有 Unity 组件。只是将其作为一种扩展方法,让生活更轻松。
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;
}
}
用法:
gameObject.AddComponentExt("YourScriptOrComponentName");
了解我是如何做到这一点很重要,这样您就可以在以后的任何 Unity 更新中添加对新组件的支持。
对于用户创建的任何脚本:
1。找出需要在Assembly.Load 函数中的??? 中包含的内容。
Assembly asm = Assembly.Load("???");
您可以通过将其放入脚本中来做到这一点:
Debug.Log("Info: " + this.GetType().Assembly);
我得到了:Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
我们现在应该用它替换 ???。
Assembly asm = Assembly.Load("Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
2。找出需要在asm.GetType 函数中的??? 中包含的内容。
Assembly asm = Assembly.Load("Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
Type type = asm.GetType(???);
在这种情况下,它只是您要添加到游戏对象的脚本的名称。
假设您的脚本名称是NathanScript:
Assembly asm = Assembly.Load("Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
Type type = asm.GetType("NathanScript");
gameObject.AddComponent(type);
对于非用户创建的 Unity 内置脚本/组件脚本:
这方面的示例是Rigidbody、Linerenderer、Image 组件。任何不是由用户创建的组件。
1。找出需要在Assembly.Load 函数的??? 中的内容。
Assembly asm = Assembly.Load("???");
您可以通过将其放入脚本中来做到这一点:
ParticleSystem pt = gameObject.AddComponent<ParticleSystem>();
Debug.Log("Info11: " + pt.GetType().Assembly);
我得到了:UnityEngine, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
我们现在应该用它替换 ???。
Assembly asm = Assembly.Load("UnityEngine, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
2。找出需要在asm.GetType 函数中的??? 中包含的内容。
Assembly asm = Assembly.Load("UnityEngine, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
Type type = asm.GetType(???);
您可以通过将其放入脚本中来做到这一点:
ParticleSystem pt = gameObject.AddComponent<ParticleSystem>();
Debug.Log("Info: " + pt.GetType());
我得到了:UnityEngine.ParticleSystem
请记住,这里使用ParticleSystem 作为示例。因此,将转到asm.GetType 函数的最终字符串将按如下方式计算:
string typeString = "UnityEngine." + componentName;
假设你要添加的组件是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);
把它放在一个扩展方法中:
如您所见,添加您创建的脚本和 Unity 附带的脚本/组件需要完全不同的过程。您可以通过检查类型是否为null 来解决此问题。如果类型为null,则执行其他步骤。如果另一个步骤也是null,那么脚本只是不退出。