unity的锁帧和垂直同步

垂直同步(VSync)

你可以把垂直同步理解为**"游戏向手机屏幕妥协",手机屏幕有一个固定的刷新率。比如大部分普通手机屏幕是 60Hz(一秒钟刷新 60 次画面),好一点的手机是 120Hz。 如果开启了垂直同步(VSync),就等于告诉游戏:"你出图的速度,必须严格配合**屏幕刷新的节奏"。

如果屏幕是 60Hz,开启垂直同步后,游戏最高只能跑 60帧。如果系统判断手机发热降频,跑不满 60 帧了,垂直同步会非常粗暴地把游戏的帧率直接腰斩,也就是强制掉到 30帧。哪怕你当时能跑 55 帧,它为了和屏幕节奏同步,也会硬生生给你降到 30 帧。

那么unity里的api接口是用来干嘛的呢?

Application.targetFrameRate = 30;

在 Unity 引擎的底层规则里:垂直同步(VSync)的优先级 高于 代码锁帧(targetFrameRate)。

所以:

假设一台手机屏幕是 60Hz,同时你开启了垂直同步:

1.场景A:你想锁 120 帧 代码执行:Application.targetFrameRate = 120; 结果:游戏只会跑 60帧。因为垂直同步把帧率上限死死卡在了屏幕的最高刷新率(60Hz)上,你代码写再高都没用。

2.场景B:你想锁 30 帧,但系统强制插手 在一些安卓手机上,由于底层驱动或系统魔改的原因,只要开了垂直同步,系统发现游戏性能良好,可能会无视你的 targetFrameRate = 30,硬生生把帧率拉高去匹配 60Hz 屏幕刷新率,导致你的省电策略(非战斗锁 30 帧)失效,手机反而发热。

3.场景C:你想锁 60 帧,但性能偶尔波动 代码执行:Application.targetFrameRate = 60;。 本来游戏性能可以跑到 58 帧(玩家感受不到明显卡顿)。但因为开了垂直同步,这 58 帧无法和 60Hz 屏幕完美对齐。于是垂直同步机制会触发"腰斩"效应,把你的帧数瞬间降到 30 帧,玩家会感觉突然卡了一下。

垂直同步(VSync)最大的作用就是解决画面撕裂(Screen Tearing),其次是防止显卡过劳(节能降温)。

作用 1:解决"画面撕裂"(最核心的作用)

1.没有垂直同步的时候(自由奔跑): 显卡(渲染画面的老大哥)和屏幕(显示画面的小老弟)是各干各的。 显卡只要一画完一张图,就马上塞给屏幕显示。但问题是,屏幕正在从上往下一点点扫描显示上一张图(还没显示完),显卡突然硬塞进一张新图。 这就导致:屏幕上半截显示的是上一帧的画面,下半截显示的是刚刚塞进来的新一帧画面。因为游戏里的人物和镜头在移动,这两截画面是错位的,玩家就会看到一条明显的横向断层,这就是画面撕裂。特别是当玩家快速转动镜头时,撕裂会非常严重。

2.开启垂直同步之后(排队等候): 相当于给显卡立了个规矩:"你画得再快也没用,必须等屏幕把当前这张图完整显示完了,你才能把下一张图交出去。" 这样屏幕每次显示的都是完整的一帧,画面就变得非常平滑、完整,不再有错位撕裂的现象。

作用 2:防止显卡"空转"(节能、降温)

假设你的屏幕只有 60Hz 的刷新率(一秒只能显示 60 张图)。

如果不开垂直同步,也不用代码锁帧,显卡可能会拼命干活,跑出 120 帧。

多跑出来的那 60 帧,屏幕根本来不及显示,完全是无效的劳动。这会导致手机/电脑疯狂发热、耗电量剧增。

开了垂直同步后,显卡发现屏幕一秒只要 60 张,它跑到 60 帧就会主动停下来休息。这在一定程度上起到了节能和防止设备过热的作用。

既然有用,为什么手游/Unity 经常要关掉它?

对于 PC 主机游戏,尤其是竞技类之外的 3A 大作,通常建议开启垂直同步以获得更好的画面连贯性。但在手游开发中,我们往往倾向于关掉它(把 vSyncCount 设为 0),原因如下:

  1. 争夺控制权冲突(就是你项目遇到的问题) 像之前提到的,手机的硬件和安卓系统的调度非常复杂。一旦开启垂直同步,帧率的控制权就被操作系统和底层硬件拿走了。你想在战斗外省电锁 30 帧?你想做极致省电模式锁 10 帧?不好意思,系统开了垂直同步可能强制把你拉满,或者在性能波动时疯狂掉帧(比如只能跑 55 帧时被强行锁到 30 帧)。为了让代码里的 Application.targetFrameRate 绝对生效,开发者必须关掉垂直同步。

  2. 增加输入延迟(操作变"肉") 垂直同步要求显卡等屏幕,这意味着你按下技能键后,画面要多排一会儿队才能显示出来。这就产生了所谓的"输入延迟"(Input Lag)。在要求反应速度的动作游戏或竞技游戏里,玩家会觉得按键"不跟手"、"滑步"。关掉垂直同步能获得最直接的响应速度。

总结

垂直同步的优点:防画面撕裂,使画面平滑。

在你们项目中的弊端:会剥夺代码控制帧率的权限,导致你写的省电逻辑、30/60帧切换逻辑统统失效或行为异常。

所以,常规的手游做法是:关闭垂直同步,然后用代码(Application.targetFrameRate = 60 等)来控制最高帧数,以此来防止手机过热,同时保留对帧率的绝对控制权。 虽然这偶尔会有极轻微的画面撕裂,但在手机那么小的屏幕上,玩家通常很难察觉到。

简单理解:Application.targetFrameRate = 120 ,unity告诉CPU和GPU每秒钟渲染产生出120张图出来,至于屏幕能不能一秒钟画120张图取决于手机屏幕的刷新率,如果这个手机很垃圾,就是它的屏幕刷新率是30Hz,那它每秒钟只能画30张图,如果这种手机上设置了120帧,那么每秒屏幕还是画30张图,多余的90张图就浪费了。所以会白白浪费CPU和GPU的电力和算力,玩家手机会耗电很快,并且很烫,但是并不能带来画面观感上的提升。

相关推荐
承渊政道3 小时前
飞算Java炫技赛:Java×Unity数字孪生园区平台的从零落地记录
java·开发语言·unity·技术分享·vibe coding·飞算javaai·飞算java ai炫技赛
unityのkiven12 小时前
Unity 共享材质修改问题与 MaterialPropertyBlock 解决方案
unity·游戏引擎·材质
丁小未13 小时前
Unity 极致高效的IM设计方案教程
unity·性能优化·游戏引擎·im
unityのkiven13 小时前
Unity UGUI 中 EventTrigger 导致 ScrollRect 鼠标滚轮失效的问题分析与解决
unity·计算机外设·游戏引擎
丁小未17 小时前
Unity动态图集方案
unity·游戏引擎
元气少女小圆丶20 小时前
停止单机,开始学一点后台通信吧
unity
丁小未21 小时前
Unity高效的DOTS动画方案Rukhanka深度剖析
unity·游戏引擎·rukhanka·dots动画·gpu动画·gpuecsanimation
unityのkiven1 天前
Unity 中的 Mesh 和 Renderer 详解:从模型数据到画面显示
unity·游戏引擎