Unity事件及MonoBehaviour


先来说一说反射。

元数据

有关程序及其类型的数据被称为元数据,他们保存在程序的程序集中。

反射

一个运行的程序查看本身的元数据或其他程序的元数据的行为叫做反射

C#中和反射相关的一个类是System.Type。程序中的每一个类型都会关联一个Type对象。Type对象包含了有关类型的很多信息:

  • Name:类型的名字
  • NamespaceAssembly
  • GetFields(), GetProperties(), GetMethods()

获得Type对象的方法:

  • 通过System.object.GetType()
  • 使用typeof运算符

大家都很关心的一个问题,为什么反射很。当我们使用反射时(C#),实际发生了什么1

  1. 获取方法/字段/属性信息。当然,有Info Cache机制可以节省之后再调用反射的时间。
FieldInfo f = foo.getType().GetField("some_field");
  1. 验证参数以及错误处理:在invoke时验证类型是否匹配,验证参数的类型和数量。抛出异常。
  2. 安全检查:这个主要是.Net的Code Access Security Permission
特性

特性是一种语言结构;通过特性,我们可以向程序的程序集增加元数据


Update()是怎么工作的

Unity的Update()等事件机制并不是通过反射实现的2

Unity会通过runtime来检视是否一个MonoBehaviour具有Update()之类的方法,并将这种信息缓存起来。(可以通过Script Execution Order选项来手动调节这些Updates的执行顺序,或通过特性)

Unity的BehaviourManager会统一调度Updates等方法,这里面会涉及到Bahaviour对象的遍历,检查调用的合法性,为调用做准备,检查GameObject是否激活等工作,会造成一定的时间开销。使用Update()是十分易于开发的,追求效率的话或许可以手动实现一个manager

(一种可行的方法是,让manager继承自MonoBehaviour,并提供注册函数和相应的Array。其余的脚本继承自manager,这样全局就只有一个Update()了)


协程

C#语言原本就有yield和IEnumrator。惰性求值

IEnumerator ie;
public Start() {
    ie = Loop();
}
void Loop() {
    int i = 0;
    while (true) {
        yield return i++;
    }
}
void Update() {
    if (ie.MoveNext()) {
        Debug.Log(ie.current);
    }
}

Unity协程不是并行的。

Unity协程的magic效果在于:通过StartCoroutine()将任务函数委托给协程执行器(猜想)执行,可以设定WaitForSeconds()来决定执行间隔。yield类型的协程调用时机是每一帧的Update()之后

void Start() {
    StartCoroutine(Loop());
}
void Loop() {
    int i = 0;
    while (true) {
        yield return new WaitForSeconds(1.0f);
    }
}

Unity协程的适用情形:

  • 需要每帧执行的任务:使用协程可以让代码美观简洁(for循环简单明了)。
  • 有一定的时间间隔,且时间间隔大于每帧时间的情况。

协程的另一个注意点就是通过方法名启动时使用了反射机制,消耗较大。


脚本生命周期

Update:每帧调用一次,它是帧更新的主要功能。
FixedUpdate:和帧率实际是有关的。使用独立的定时器。如果帧率较高,它就每一帧少调用几次,反之亦然。
LateUpdate:也是每帧调用一次,在Update之后。它的经典用法是摄像机跟随。

各个脚本的生命周期官网讲的很清楚了3img


MonoBehaviour

有了以上的介绍,MoneBehaviour的行为仅很好理解了。

  • InvokeInvoke相关的方法都是反射相关的
  • Coroutine:协程

  1. https://mattwarren.org/2016/12/14/Why-is-Reflection-slow/ ↩︎

  2. https://blogs.unity3d.com/2015/12/23/1k-update-calls/ ↩︎

  3. https://docs.unity3d.com/Manual/ExecutionOrder.html ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值