我正在尝试复制Unity 3D引擎的MonoBehaviour
。我在Linux上使用monodevelop,大多数测试将在Windows中完成。
有关MonoBehavior.Start
的更多信息,请参阅here。
我想在从MonoBehavior继承的所有类型上调用Start
方法。
这就是我的尝试:
class MonoBehaviour
{
static Type[] types = Assembly.GetExecutingAssembly().GetTypes();
public static void Main ()
{
foreach (Type type in types)
{
if (type.IsSubclassOf(typeof(MonoBehaviour)))
{
MethodInfo minfo = type.GetMethod ("Start");
mInfo.Invoke (type, null); // This throws
}
}
}
}
class example : MonoBehaviour
{
void Start()
{
// I want this to be run from MonoBehaviour
Console.WriteLine ("HelloWorld");
}
}
class example1 : MonoBehaviour
{
}
答案 0 :(得分:1)
编辑完全重做这个答案,因为现在我相信我知道你在问什么。
我将为您提供代码,允许您在程序集中调用Type的每个对象的Start。但是,我不认为这是MonoBehavior的工作原理。还有更多要考虑的问题。例如,应首先调用Awake
,并且存在是否已启用脚本的条件。此外,我不认为这个方法一次被调用所有对象,但也许只有在创建/启动对象时。我没有Unity 3D体验,所以我对这些细节一无所知。我只依赖于你从问题中的链接中读到的内容。
我添加了一些额外的绑定标志,以表明这可以找到各种范围的方法。此外,在我的代码中,我明确地寻找没有参数的Start
方法。这可以根据您的需要和喜好进行修改。
using System;
using System.Reflection;
class Program
{
static void Main(string[] args)
{
Assembly asm = Assembly.GetExecutingAssembly();
Type[] types = asm.GetTypes();
foreach (var type in types)
{
if (type.IsSubclassOf(typeof(MonoBehavior)) || type.GetInterfaces().Contains(typeof(MonoBehavior)))
{
MethodInfo startMethod = type.GetMethod("Start", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { }, null);
if (startMethod != null)
{
ConstructorInfo ctor = type.GetConstructor(new Type[] { });
if (ctor != null)
{
object inst = ctor.Invoke(new object[] { });
startMethod.Invoke(inst, new object[] { });
}
}
}
}
}
}
interface MonoBehavior
{
}
class Example1 : MonoBehavior
{
static void Start()
{
Console.WriteLine("Example1 Start");
}
}
class Example2 : MonoBehavior
{
}
现在,如果你不喜欢创建一个对象,你可以使Start
为静态,并且反射中的几行会像这样调整:
MethodInfo startMethod = type.GetMethod("Start", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static, null, new Type[] { }, null);
if (startMethod != null)
{
startMethod.Invoke(null, new object[] { });
}
请注意,我不再需要创建实例,并且传递给Invoke
的第一个参数为null(这总是针对static
方法完成)。
但是,我不会从阅读MonoBehaviour.Start
上的Unity3D文档中得到印象,它打算以这种方式运行,更不用说静态了。我认为应该在其他各种条件下创建MonoBehaviour
时运行。该模型不需要反射,但我建议构建一种工厂模型,在工厂对象的请求中创建MonoBeaviour
对象 - 调用相应的Awake
和Start
返回实例之前的方法。
答案 1 :(得分:0)
类型不是它自己的子类,这就是为什么你有三种类型但只有2种匹配条件的原因。 (如果那是问题。)此外,MonoBehaviour没有Start()方法,或者我很累; - )。