我正在尝试复制Unity 3D引擎的MonoBehaviour
。我在Linux上使用monodevelop,大多数测试都将在Windows Unity 3D engine editor
中完成。
有关MonoBehaviour.Update
的更多信息,请参阅here
我想对每隔10毫秒从Update
继承的所有类型调用MonoBehavior
方法。
这就是我在使用Start
的方式using System;
using System.Reflection;
public class MonoBehaviour{
public static void Main (){
Type[] types = Assembly.GetExecutingAssembly().GetTypes();
foreach (Type type in types) {
if (type.IsSubclassOf(typeof(MonoBehaviour))){
System.Reflection.MethodInfo mInfo = type.GetMethod ("Start", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { }, null); // it is run 2 times
if (mInfo != null) {
ConstructorInfo ctor = type.GetConstructor (new Type[] { });
if (ctor != null) {
object inst = ctor.Invoke (new object[] { });
mInfo.Invoke (inst, new object[] { });
}
}
}
}
}
}
class example : MonoBehaviour{
void Start(){
// this works perfectly
Console.WriteLine ("HelloWorld");
}
void Update(){
// I want this to be run every 10 ms
Console.WriteLine ("HelloinUpdate");
}
}
答案 0 :(得分:2)
你可以不使用反射来做到这一点,它会更快(更安全):
using System;
using System.Linq;
using System.Timers;
public static class Program
{
public static void Main()
{
IEnumerable<Type> assemblyTypes = typeof(MonoBehaviour).Assembly.GetTypes();
IEnumerable<Type> behaviourTypes = assemblyTypes
.Where(type => typeof(MonoBehaviour).IsAssignableFrom(type))
.Where(type => !type.IsAbstract);
List<MonoBehaviour> behaviours = behaviourTypes
.Select(Activator.CreateInstance)
.Cast<MonoBehaviour>()
.ToList();
foreach (MonoBehaviour monoBehaviour in behaviours)
{
monoBehaviour.Start();
}
var timer = new Timer(10 /* Milliseconds */);
timer.Elapsed += (sender, eventArgs) =>
{
foreach (MonoBehaviour monoBehaviour in behaviours)
{
monoBehaviour.Update();
}
};
timer.Start();
Console.WriteLine("Press a key to stop.");
Console.ReadKey();
}
}
public abstract class MonoBehaviour
{
public virtual void Start()
{
}
public virtual void Update()
{
}
protected static void Log(string message)
{
Console.WriteLine("{0} - {1}", DateTime.Now, message);
}
}
public class Behaviour1 : MonoBehaviour
{
public override void Start()
{
Log("Behaviour1 - Start");
}
public override void Update()
{
Log("Behaviour1 - Update");
}
}
public class Behaviour2 : MonoBehaviour
{
public override void Start()
{
Log("Behaviour2 - Start");
}
public override void Update()
{
Log("Behaviour2 - Update");
}
}:
输出将是这样的(我将计时器调整为1000毫秒):
答案 1 :(得分:0)
基本上,这样的事情可以解决问题:
var timer = new Timer(10);
timer.Elapsed += new ElapsedEventHandler(MonoBehavior.Update);
timer.Start();
它创建一个10ms的计时器,然后将您的方法绑定到已用事件并使计时器倒计时。当它达到0时,事件被触发并且时间重置。
答案 2 :(得分:0)
使用Timer
:
Timer t = new System.Threading.Timer(Update, this, 10, 10);