IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 【Unity】使用FixedUpate以及Upate的注意点 -> 正文阅读

[游戏开发]【Unity】使用FixedUpate以及Upate的注意点

【Unity】使用FixedUpate以及Upate的注意点

前言

在实际使用Update和FixedUpdate时,遇到一些操作在FixedUpdate不生效的情况。在网上找了一圈要么是一些还没官方文档通俗易懂的定义,要么没有解释到位没能解惑,于是自己根据官方文档分析并通过自己测试做出一些总结。

一、定义

先放出官方解释:MonoBehaviour-FixedUpdate() - Unity 脚本 API

Update:按实际帧率调用,受运行时设备的性能及一帧需要渲染物件数量和质量的影响。 游戏从场景简单的地方移动到场景复杂的地方时会出现卡顿,往往就是一帧中加载的东西突然增加,加载时间变长导致帧数变少。

FixedUpdate:按固定的帧率调用,根据设置步长固定间隔的执行。例如:设置50帧,那么不管实际帧中一帧执行了多少秒,FixedUpdate固定每0.02s调用一次。

二、deltaTime和fixedDeltaTime

Time.deltaTime在官方的定义为:完成上一帧所用的时间(以秒为单位),用通俗易懂的话来描述就是,每一帧所间隔的时间。而Time.fixedDeltaTime也能适用于该解释。

例如:50fps,那么对于fixedDeltaTime就是一个固定值0.02。而deltaTime会受设备性能和渲染情况影响,可能前10帧不稳定足足加载了0.4s,平均每帧0.04s,剩下的40帧平均一下就只剩0.015s了。

在Update中使用位移相关的逻辑时,就会有人建议用速度?Speed * Time.deltaTime?使操作边顺滑,这就类似于权重计算,因为1s的Time.deltaTime的和为1,这就确保了每秒位移的距离是相同的。但这么使用实际上只是解决了单位时间位移不同的问题,在帧率变换明显时这种做法还是会显得卡顿。

想象一下,你的角色正在以匀速10m/s的速度狂奔,突然跑到了新环境帧率猛地降到了10fps,第1帧加载了0.6s,后9帧加载0.4s,虽然因为使用了Speed * Time.deltaTime使得你的角色这一秒和前面一样都跑了10m,但毫无疑问你会看到你的角色闪现了一下。

基于上述情况,把处理物理逻辑的代码放到固定时间执行的FixedUpdate中处理会更加流畅,不会因为实际帧率的变化导致刷新角色行为变得时快时慢(简单说就是一卡一卡的,甚至发生“闪现”)。

三、FixedUpdate中跳跃失效问题

那么一股脑把物理逻辑的代码都放入FixedUpdate就行了吗?有问题!

例如控制角色跳跃(Jump)的KeyDown或ButtonDown放在FixedUpdate中,会出现 按键没有反应 或 按下一次键执行了多次 的情况。根据官方文档对FixedUpdate的解释不难推测,FixedUpdate的执行是基于实际帧的。

实际帧率100fps > 固定帧率 50fps的情况 ,FixedUpdate是较为均匀的在这100帧中每2帧执行一次。如果KeyDown或ButtonDown事件触发在实际帧的1帧,3帧,4帧,7帧...,而FixedUpdate是在实际帧的2帧,4帧,6帧,8帧执行,那么就会出现“丢帧”,漏掉了1帧,3帧,7帧,只执行了第4帧的事件。

实际帧率25fps < 固定帧率50fps的情况,FixedUpdate就在每0.02s较为均匀的多次执行实际帧内容。如果KeyDown或ButtonDown事件触发在实际帧的 1帧(0.05s),2帧(0.03s), 3帧(0.06s)总计0.14s,而FixedUpdate就可能在这0.14s中执行了7次实际帧触发的事件,导致3次按键产生了7次响应。

这里提供一种验证方式,在FixedUpdate中写一个KeyDown或ButtonDown事件,分别调节FixedUpdate的固定帧率大致为实际帧率的0.25倍,0.5倍,1倍,1.5倍,2倍,然后快速或匀速按键。结果会发现按键次数和打印日志次数跟这个倍数相符合。(比如:固定帧率为实际帧率的0.25倍(1/4),那么就能看到大概按键4次打印一次结果)

void FixedUpdate()
{
  if (Input.GetKeyDown(KeyCode.Q))
  {
    print("Q key pressed");
  }
}

图中为固定帧率和实际帧率近似1:1的情况

四、对Update和FixedUpdate的一些使用建议

基于上述结论,把物理逻辑部分放在FixedUpdate中时,

如果涉及到一些单次按键的情况,考虑到可能会出现“丢帧”,可以把这些单次按键的输入检测放在Update中,确保能捕获到该事件。

void Update()
{
  if(Input.GetKeyDown(KeyCode.Q))
    isPressed = true;
}

void FixedUpdate()
{
  if (isPressed)
  {
    //执行触发按键的一些逻辑
    isPressed = false;
  }
}

?

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-11-05 00:54:29  更:2022-11-05 00:55:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/22 19:44:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码