经过广泛的实验,我成功得到了这个。它也涵盖了所有的Unity组件。只是将其制作为扩展方法,让生活更加简单。
public static class ExtensionMethod
{
public static Component AddComponentExt(this GameObject obj, string scriptName)
{
Component cmpnt = null;
for (int i = 0; i < 10; i++)
{
cmpnt = _AddComponentExt(obj, scriptName, i);
if (cmpnt != null)
{
break;
}
}
if (cmpnt == null)
{
Debug.LogError("Failed to Add Component");
return null;
}
return cmpnt;
}
private static Component _AddComponentExt(GameObject obj, string className, int trials)
{
const string userMadeScript = "Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null";
const string builtInScript = "UnityEngine, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null";
const string builtInScriptUI = "UnityEngine.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
const string builtInScriptNetwork = "UnityEngine.Networking, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
const string builtInScriptAnalytics = "UnityEngine.Analytics, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null";
const string builtInScriptHoloLens = "UnityEngine.HoloLens, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null";
Assembly asm = null;
try
{
switch (trials)
{
case 0:
asm = Assembly.Load(userMadeScript);
break;
case 1:
className = "UnityEngine." + className;
asm = Assembly.Load(builtInScript);
break;
case 2:
className = "UnityEngine.UI." + className;
asm = Assembly.Load(builtInScriptUI);
break;
case 3:
className = "UnityEngine.Video." + className;
asm = Assembly.Load(builtInScript);
break;
case 4:
className = "UnityEngine.Networking." + className;
asm = Assembly.Load(builtInScriptNetwork);
break;
case 5:
className = "UnityEngine.Analytics." + className;
asm = Assembly.Load(builtInScriptAnalytics);
break;
case 6:
className = "UnityEngine.EventSystems." + className;
asm = Assembly.Load(builtInScriptUI);
break;
case 7:
className = "UnityEngine.Audio." + className;
asm = Assembly.Load(builtInScriptHoloLens);
break;
case 8:
className = "UnityEngine.VR.WSA." + className;
asm = Assembly.Load(builtInScriptHoloLens);
break;
case 9:
className = "UnityEngine.AI." + className;
asm = Assembly.Load(builtInScript);
break;
}
}
catch (Exception e)
{
}
if (asm == null)
{
return null;
}
Type type = asm.GetType(className);
if (type == null)
return 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")
找出在
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");
找出在`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
,那么该脚本将简单地不存在。
assembly.GetTypes().Any(t => t.Name == scriptname);
。 - mrogal.ski