unity基础简介(二)

本文介绍了Unity中Monobehaviour的生命周期,包括Awake、OnEnable、Start、FixedUpdate、Update和LateUpdate等函数的调用时机。详细讨论了在游戏开发中为何多线程技术不常用于游戏主体,以及如何自定义生命周期函数的调用顺序。此外,还解析了Unity内部的PlayerLoop和DelayedCallManager如何管理这些函数的调用。
摘要由CSDN通过智能技术生成

unity基础简介(二)

monobehaviour是什么

前言

由于游戏的特殊性,多线程技术很难应用在游戏开发过程中,试想我们用另一个线程去控制物件,除非他们与其他事物没有任何交互,否则每一次交互都需要进行线程同步,即使你只是一个在背景里走来走去的无害NPC,与什么都不需要交互,但是为了避免玩家的显示中出现什么奇怪现象(比如步子迈大了),也必须要进行帧同步,让每一次update都需要线程同步,因此多线程技术大多无法用在游戏主体中,通常都是资源加载,网络通信等工作,游戏的大部分逻辑都运行在unity的主线程中,unity的主线程维持生命周期函数

unity生命周期

在这里插入图片描述

暂且不提动画,渲染和协程

Awake():在创建对象,比如实例化预制体后,Start函数之前执行(如果游戏对象在启动期间处于非活动状态,则在激活之后才会调用 Awake)

OnEnable():(仅在对象处于激活状态时调用)在启用对象后立即调用此函数。在创建 MonoBehaviour 实例时(例如加载关卡或实例化具有脚本组件的游戏对象时)会执行此调用。

Start:仅当启用脚本实例后,才会在第一次帧更新之前调用 Start。

当物体被实例化后,如果没有激活,则不调用函数,当实例化并激活后依次调用Awake,OnEnable,start,Awake和start只会被调用一次,但active和enable发生改变时OnEnable,OnDisEnable会被调用

在图中物理部分有自己的循环,它们的更新频率是一致的

FixedUpdate:调用 FixedUpdate 的频度常常超过 Update。如果帧率很低,可以每帧调用该函数多次;如果帧率很高,可能在帧之间完全不调用该函数。在 FixedUpdate 之后将立即进行所有物理计算和更新。在 FixedUpdate 内应用运动计算时,无需将值乘以 Time.deltaTime。这是因为 FixedUpdate 的调用基于可靠的计时器(独立于帧率)。

Update:每帧调用一次 Update。这是用于帧更新的主要函数。

LateUpdate:每帧调用一次 LateUpdate(在所有 Update 完成后)。LateUpdate 开始时,在 Update 中执行的所有计算便已完成。LateUpdate 的常见用途是跟随第三人称摄像机。如果在 Update 内让角色移动和转向,可以在 LateUpdate 中执行所有摄像机移动和旋转计算。这样可以确保角色在摄像机跟踪其位置之前已完全移动。

FixedUpdate与Update:
FixedUpdate:每帧调用而且每帧的时间间隔是固定的,不受帧率(FPS)影响。每一帧的时间是在Edit->Project Settings->Time面板中的Fixed Timestep设置,默认为0.02s,则0.02s为一帧也就是每帧之间的间隔是0.02s。
对于更新频率比较稳定的物理系统来说就合适放在FixedUpdate中处理
Update:每帧调用但是每帧的时间间隔不固定,受到帧率影响,而帧率(FPS)与电脑性能有关。
例如FPS是30,则每秒执行30帧,如果FPS是10,则每秒执行10帧。是不稳定的。

当有多个脚本时可以自定义相同周期函数的调用顺序,点击excution order
在这里插入图片描述

monobehaviour简介

在这里插入图片描述

可以看到monobehaviour的继承关系,继承自Object(这里是unity中的Object)可以让脚本被Destroy,Find或Instantiate,继承自Component可以让脚本被挂在游戏对象上,且可以获取游戏对象或其子对象的其他组件,也就是用的最多的GetComponent,还可以获取游戏对象的其他属性,具体可以F12查看声明,继承自MonoBehavior让脚本使用生命周期函数,并按照生命周期进行调用。

生命周期函数是如何被调用的

首先生命周期函数都是private,那么调用就需要使用反射,然而.net的反射机制开销很大,GetType需要搜寻类型,因此unity不可能使用这种方法,有人指出unity使用mono的api,它支持基于字符串查找方法,并将指针保存。

在unity源码中维护了一个PlayerLoop用于每帧循环,生命周期函数的调用依靠其中的延迟调用管理(DelayedCallManager),它提供计时能力,在一段时间后回调;提供顺序控制能力,在PlayerLoop其他阶段执行回调;提供取消回调功能

DelayedCallManager提供一下几种模式:

enum DelayedCallMode
{
   
    kRunFixedFrameRate     = 1 << 0,
    kRunDynamicFram
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值