尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Cocos Creator 3.8.2 多分辨率适配:设计分辨率、Fit 策略与 Widget 实战

Cocos Creator 3.8.2 多分辨率适配:设计分辨率、Fit 策略与 Widget 实战 做 Cocos Creator 的人早晚都会收到这类消息策划发来一张截图说这个按钮怎么在 iPhone 上歪了测试填了一条 bug折叠屏开合之后 UI 全跑偏你自己在浏览器模拟器里怎么切机型都没事一上真机就原形毕露。CocosCreator3.8.2 的多分辨率适配没有那么多玄学核心就是三件事设计分辨率定得清醒、Canvas 的 Fit 策略选得对、关键 UI 元素用 Widget 钉住。三件事理顺之后横竖屏自动翻转也不过是一层屏幕监听的事。这篇文章我打算把背后的缩放原理讲明白再给一个可以直接抄作业的完整 Demo——从项目设置到真机验证的每一步都拆开照着走一遍 5 分钟绰绰有余。1. 屏幕那么多适配到底在解决什么问题1.1 从 16:9 到折叠屏你面对的是一堆矩形先别急着动手改项目搞清楚问题本质比记住配置重要得多。你做一个游戏美术资源按一套固定尺寸画这套尺寸就是设计分辨率但玩家手里的设备五花八门iPhone 14 Pro Max 是 20:9 左右安卓中端机大量是 19.5:9 和 18:9iPad 是 4:3 或 3:2折叠屏展开后接近 1:1 甚至更方PC 端浏览器窗口更是想怎么拉就怎么拉。单看竖屏游戏屏幕宽高比从 16:91.78到 21:92.33都有差距超过 30%。如果你的界面在 16:9 上刚好铺满到了 21:9 的机型上高度方向的可用空间完全是另一回事。Cocos Creator 的适配机制本质上就是一句话把设计坐标系映射到物理像素坐标系。它不可能让所有设备都原样显示设计稿必须做取舍。问题只是——你希望它在你最在乎的那些机型上优先保哪一边。1.2 三种翻车现场拉伸、黑边、裁切没做过适配的人第一反应往往是把 UI 拉满全屏不就行了于是踩进三种典型坑拉伸变形直接把设计稿等比或非等比拉伸填满屏幕圆按钮变椭圆字被压扁。对应 Cocos 的EXACT_FIT策略绝大多数情况下不该用于正式 UI。黑边/红边等比缩放保证设计内容完整可见但屏幕比例不同时两侧或上下会空出一块。Cocos 里叫SHOW_ALL露出的那圈背景色就是设计分辨率以外的区域调试时经常是醒目的红色。裁切为了铺满屏幕而放大超出范围的内容直接裁掉对应NO_BORDER。背景图看不出来但按钮贴边就会被切掉一半。这三种情况没有绝对的对错是取舍。你要做的是根据玩法判断哪些内容是无论如何必须完整显示的哪些是可以裁掉的无边界资源。游戏 UI 里通常必须完整显示的是信息区和可点击元素可以裁掉的是背景、装饰粒子这类铺底资源。1.3 三个绕不开的概念设计分辨率、可见区域、安全区正式动手配置前先统一三个词的含义后面说到哪一步都不会晕设计分辨率项目设置里填的尺寸也是美术资源出图的基准坐标系。竖屏常用 720×1280横屏常用 1280×720。在这个坐标系里原点在屏幕中心x 向右、y 向上Widget 组件就是帮你按边、角、中心做对齐的工具。可见区域visible size当前设备上在设计坐标系这个虚拟世界里能看到的矩形大小。设备宽高比不同可见区域会变。调试时打印view.getVisibleSize()多数适配问题都能从它身上看出原因。安全区刘海、挖孔、底部手势条占用的物理区域之外系统保证不会被遮挡的部分。iPhone 竖屏刘海在顶部横屏刘海在左右两侧安卓挖孔位置更是千奇百怪所以顶部缩多少、底部缩多少绝不能写死。这三者搞明白接下来的配置就不再是照着勾选而是带着依据做决策。2. 五步配置设计分辨率、Fit 策略与 Widget2.1 设计分辨率到底填多少在 Cocos Creator 3.8.2 里菜单栏点项目 → 项目设置 → 项目数据里面就是设计宽度和设计高度两个输入框。我自己的习惯新项目直接按目标主机的比例来。竖屏用 720×1280正好 16:9横屏用 1280×720。为什么偏爱这两个值因为 16:9 是当前最主流的宽高比基线美术出图、UI 标注都好换算而且这个分辨率不算大资源尺寸和内存占用都友好。如果你的游戏要横竖屏都支持那稍微麻烦一点通常有两种做法一是锁定一个设计分辨率、用 Widget 做灵活布局二是我后面 Demo 用的做法——检测到朝向变化时运行时切换设计分辨率。先记住结论设计分辨率是坐标系不是画质。真机上资源会按屏幕密度自动缩放你不需要为了让高像素手机更清晰而去调大设计分辨率画质问题由资源尺寸决定。2.2 Fit Width / Fit Height勾哪个为什么Canvas 组件上有两个勾选项Fit Height 和 Fit Width。网上很多人记口诀竖屏勾 Fit Height横屏勾 Fit Width这个口诀太粗了。两个都勾、只勾一个、都不勾对应的是完全不同的缩放策略。我把背后的数学拆开以后你遇到任何奇葩比例都能自己判断。以竖屏游戏、设计分辨率 720×1280 为例。假设真机是 1080×234019.5:9只勾 Fit Height引擎把设计坐标的高度映射到屏幕物理高度缩放系数为 1280 / 2340 ≈ 0.547。屏幕物理宽度 1080 对应设计坐标宽度为 1080 × 0.547 ≈ 591。设计宽度是 720所以左右各被裁掉约 64.5 个设计单位。结论屏幕越细长左右被裁得越多。只勾 Fit Width缩放系数为 720 / 1080 ≈ 0.667。屏幕物理高度 2340 对应设计坐标高度为 2340 × 0.667 ≈ 1560。设计高度只有 1280上下各多出 140 个设计单位的额外空间。结论屏幕越细长上下的扩展空间越大UI 元素必须用 Widget 往中间收否则设计稿里顶到边缘的元素实际碰不到屏幕边缘。再举横屏例子设计分辨率 1280×720真机 2340×1080同样是 19.5:9只是横过来。只勾 Fit Width缩放系数为 1280 / 2340 ≈ 0.547可见高度为 1080 × 0.547 ≈ 591设计高 720上下各裁 64.5。只勾 Fit Height可见宽度为 2340 × 0.667 ≈ 1560设计宽 1280左右各多出 140。所以两个字的口诀永远有例外。真正的选择逻辑是如果这个方向的元素被裁掉会出事就优先保证这一边完整。举个例子横屏射击游戏的敌人从屏幕两侧进场左侧被裁了没法玩必须 Fit Width同时上下留出可裁空间竖屏消除游戏的底部操作区不能丢就 Fit Height左右留出可裁空间。我做项目时的默认组合是Canvas 上 Fit Width 和 Fit Height 都勾也就是NO_BORDER策略。这样背景永远铺满整个屏幕重要 UI 全部用 Widget 收进一个绝对安全区。代价是安全区得留足够大因为不同比例下可见区域的形状在变。策略对照表整理如下策略组合缩放行为典型用途Fit Width Fit Height等比放大到铺满超出裁剪NO_BORDER背景、无边界场景、全屏 UI只勾 Fit Height高度固定宽度视比例被裁或扩展FIXED_HEIGHT竖屏玩法完整、UI 集中在中央只勾 Fit Width宽度固定高度视比例被裁或扩展FIXED_WIDTH横屏玩法完整、UI 集中在中央都不勾等比缩小到完整显示出现空边SHOW_ALL测试、想保留整张设计稿如果你在代码里直接用view.setDesignResolutionSize记得把传入的策略和 Canvas 组件上的勾选保持一致比如都对应NO_BORDER否则编辑器面板的勾选和代码逻辑会在某些版本里互相覆盖现象就是改了没反应或者布局跳变。保证两者方向一致是最省心的做法。2.3 Widget把 UI 元素钉在正确的位置Widget 组件的作用是让节点相对父节点钉在某条边或某个中心上。它是在尺寸变化时计算对齐的不是每帧实时跟随这一点后面讲屏幕旋转时会用到。常用配置我直接给参考顶部标题勾选 Top数值填安全区顶 预留边距再勾 Horizontal Center 让标题水平居中。底部按钮组勾选 Bottom再勾 Horizontal Center。左侧菜单勾选 Left再勾 Vertical Center。背景层把 Left、Right、Top、Bottom 全勾上数值全填 0节点会直接拉伸成可见区域的大小。用 Widget 的好处是数值直观你在设计稿里看到按钮距底边 80pxWidget 里就填 80不用自己算各种屏幕比例下的偏移。提示Widget 的对齐目标默认是父节点的矩形区域。如果你想让某组 UI 整体对齐到安全区内部就在它上面再包一层 SafeArea 容器让容器内缩内部按钮再相对容器做 Widget 对齐。2.4 刘海屏和挖孔屏安全区组件Cocos Creator 3.8.2 的组件面板里直接搜索 SafeArea就能给任意节点挂上安全区组件。它会读取当前设备的安全区数据iOS 的刘海和底部手势条、安卓的挖孔和虚拟按键区自动调整节点的位置和大小让节点内容落在安全区内。但这里有两个常见的误用第一SafeArea 加在内容容器上不要加在背景节点上。背景恰恰要覆盖到屏幕物理边缘包括刘海区域否则旋转屏幕的瞬间会出现一圈白边。正确做法是背景层直接 Widget 铺满 Canvas内容层用 SafeArea 内缩。第二SafeArea 调整的是节点矩形如果你的按钮是散着摆的节点矩形缩了按钮也不动效果很有限。所以我会把 SafeArea 挂在顶部标题容器和底部操作容器这两层上让容器整体内缩容器里的元素再各自 Widget 对齐。3. 横竖屏自动翻转构建设置与运行时监听3.1 构建面板里的屏幕方向选项如果你发布的是 Android 或 iOS 原生包屏幕方向首先由构建配置决定。Cocos Creator 3.8.2 的 Build 面板里选中 Android 或 iOS 平台后构建选项区域能找到 Orientation 相关的下拉选项一般有 Portrait、Landscape Left、Landscape Right、Sensor Landscape、Sensor Portrait、Auto/Sensor 这几类。只发布竖屏选 Portrait或者 Sensor Portrait后者允许设备上下翻转时自动转 180 度。只发布横屏选 Sensor Landscape横屏两个方向都支持。横竖屏都要选 AutoSensor引擎会跟随系统设置自动旋转旋转过程中 Canvas 的适配策略会重新计算。这里有个容易踩的点改了构建面板设置不一定立刻反映到已构建的原生工程。如果上次构建的缓存还在有些版本会出现改了朝向不生效的情况。稳妥做法是改完朝向配置后重新构建一次完整包不要只依赖增量编译。3.2 Web/H5 的方向锁定与监听浏览器端的限制比原生多不少得分开说。screen.orientation.lock()可以请求锁定方向但 iOS Safari 大部分版本不支持Android Chrome 支持而且效果还依赖用户是否开启自动旋转。所以做 H5 时我不太指望锁方向而是做两件更可靠的事第一监听尺寸变化。窗口一变立刻重新读取view.getVisibleSize()做布局刷新和日志输出。Cocos 的 screen 模块会抛出window-resize事件部分平台相当于原生 resize在这个事件里做刷新最稳。第二做一个请旋转设备浮层。如果游戏是横屏玩法检测到窗口宽高比小于 1竖屏就显示一个提示遮住画面旋转回横屏再自动隐藏。这是朴素但可靠的做法玩家体验反而比强制锁方向好。3.3 一套布局还是两套布局横竖屏自动翻转的难点从来不在翻转本身而在翻转之后 UI 往哪放。两种主流思路思路 A设计分辨率不变靠 Widget 自动吸附。适合界面元素少、横竖屏都能接受的场景。比如只有一个居中按钮和一张铺满背景旋转后 Widget 把按钮重新钉到中央背景自动拉伸。缺点在布局一旦复杂就会露馅竖屏设计在横屏下可见区域比例完全变了要不空一片要不挤成一团。思路 B检测到横竖屏变化后切换设计分辨率并显示对应的布局。竖屏用 720×1280 的设计坐标系横屏切成 1280×720然后两套布局节点分别激活。这是做双朝向项目最正经的做法代码量不大代价是维护两套节点。下面这版脚本是思路 B 的骨架放到场景根节点上即可。核心逻辑是拿view.getFrameSize()判断物理窗口宽高比然后决定当前应该用哪套设计分辨率并切换对应的布局根节点。import { _decorator, Component, Node, view, ResolutionPolicy, screen } from cc; const { ccclass, property } _decorator; const DESIGN { portrait: { width: 720, height: 1280 }, landscape: { width: 1280, height: 720 }, }; ccclass(OrientationAuto) export class OrientationAuto extends Component { property(Node) layoutPortrait: Node null; property(Node) layoutLandscape: Node null; onLoad() { screen.on(window-resize, this.onWindowResize, this); this.applyOrientation(); } onDestroy() { screen.off(window-resize, this.onWindowResize, this); } private onWindowResize() { this.applyOrientation(); } private applyOrientation() { const frame view.getFrameSize(); const isLandscape frame.width frame.height; const design isLandscape ? DESIGN.landscape : DESIGN.portrait; view.setDesignResolutionSize( design.width, design.height, ResolutionPolicy.NO_BORDER ); if (this.layoutPortrait) this.layoutPortrait.active !isLandscape; if (this.layoutLandscape) this.layoutLandscape.active isLandscape; console.log( [OrientationAuto] ${isLandscape ? landscape : portrait} design${design.width}x${design.height} visible${view.getVisibleSize().width.toFixed(0)}x${view.getVisibleSize().height.toFixed(0)} ); } }几个要注意的细节screen.off一定在onDestroy里注销不然场景销毁后回调还在触发报节点已被销毁的错切换设计分辨率后所有 Widget 会重新计算对齐但你自己用代码写死的 position 不会自动更新需要在新布局激活后手动复位Canvas 组件上的 Fit 勾选最好和代码里传的 policy 保持一致避免两者打架。4. 完整 Demo 拆解一个能横竖屏自动切换的结算界面4.1 Demo 要解决的问题这个 Demo 模拟一个典型的战斗结算界面顶部一个标题底部一个再来一局按钮中间是得分文字背景是铺满全屏的星空图。要求是竖屏时按钮在底部居中横屏时按钮挪到右侧偏下标题始终可见且不被刘海遮挡。听起来要动的地方不少其实结构非常清晰。节点树如下Canvas (Canvas 组件Fit Width Fit Height 均勾选) ├── Bg (SpriteWidget 拉伸铺满) ├── PortraitRoot (SafeArea 组件脚本控制显隐) │ └── LayoutPortrait │ ├── TopTitle (Label) │ ├── ScoreCenter (Label) │ └── BottomBtns (Button) ├── LandscapeRoot (SafeArea 组件默认隐藏) │ └── LayoutLandscape │ ├── TopTitle (Label) │ ├── ScoreCenter (Label) │ └── RightBtns (Button) └── InfoLabel (Label挂 VisibleDebug 脚本)脚本上我做了两个类OrientationAuto负责朝向检测与布局切换VisibleDebug负责把关键的可见区数据显示在屏幕上方便真机调试时一眼看出当前状态。4.2 每个节点的关键配置节点组件配置说明CanvasCanvasFit Width ✓、Fit Height ✓、alignCanvasWithScreen ✓全屏铺满采用 NO_BORDER 策略BgSpriteSimple 类型 WidgetL/R/T/B 全 0背景永远覆盖整个可见区域PortraitRoot / LandscapeRootSafeArea 组件自动避开刘海和手势条LayoutPortrait 里的 TopTitleLabel WidgetTop安全区顶30、Horizontal Center竖屏顶部标题LayoutPortrait 里的 BottomBtnsButton WidgetBottom60、Horizontal Center竖屏底部按钮LayoutLandscape 里的 TopTitleLabel WidgetTop安全区顶30、Left80横屏标题移到左上LayoutLandscape 里的 RightBtnsButton WidgetRight60、Vertical Center横屏按钮移到右中InfoLabelLabel挂 VisibleDebug实时显示 design/visible/frame 数据画重点竖屏和横屏的TopTitle和BottomBtns其实是完全独立的节点规格可以不一样。竖屏布局里按钮就做胖一点的矩形横屏布局里按钮可以做窄一点竖排三个这个自由度是两套布局方案最大的好处。4.3 核心脚本OrientationAuto 完整版在 3.3 节骨架的基础上我这里补上两个布局根节点的属性绑定和日志输出就是完整可用的版本import { _decorator, Component, Node, view, ResolutionPolicy, screen } from cc; const { ccclass, property } _decorator; const DESIGN { portrait: { width: 720, height: 1280 }, landscape: { width: 1280, height: 720 }, }; ccclass(OrientationAuto) export class OrientationAuto extends Component { property({ type: Node, tooltip: 竖屏布局根节点 }) layoutPortrait: Node null; property({ type: Node, tooltip: 横屏布局根节点 }) layoutLandscape: Node null; onLoad() { screen.on(window-resize, this.onWindowResize, this); this.applyOrientation(); } onDestroy() { screen.off(window-resize, this.onWindowResize, this); } private onWindowResize() { this.applyOrientation(); } private applyOrientation() { const frame view.getFrameSize(); const isLandscape frame.width frame.height; const design isLandscape ? DESIGN.landscape : DESIGN.portrait; view.setDesignResolutionSize(design.width, design.height, ResolutionPolicy.NO_BORDER); if (this.layoutPortrait) this.layoutPortrait.active !isLandscape; if (this.layoutLandscape) this.layoutLandscape.active isLandscape; console.log( [OrientationAuto] ${isLandscape ? landscape : portrait} design${design.width.toFixed(0)}x${design.height.toFixed(0)} visible${view.getVisibleSize().width.toFixed(0)}x${view.getVisibleSize().height.toFixed(0)} ); } }在编辑器里把 Canvas 下的 PortraitRoot 拖给layoutPortraitLandscapeRoot 拖给layoutLandscape脚本挂在 Canvas 上。跑起来之后只要改变浏览器窗口比例两套布局就会自动切换。VisibleDebug脚本很简单做一个循环刷新把运行时数据打在屏幕上import { _decorator, Component, Label, view } from cc; const { ccclass, property } _decorator; ccclass(VisibleDebug) export class VisibleDebug extends Component { property(Label) infoLabel: Label null; start() { this.schedule(this.refresh, 0.3); } private refresh() { if (!this.infoLabel) return; const design view.getDesignResolutionSize(); const visible view.getVisibleSize(); const frame view.getFrameSize(); this.infoLabel.string design : ${design.width.toFixed(0)} x ${design.height.toFixed(0)}\n visible: ${visible.width.toFixed(0)} x ${visible.height.toFixed(0)}\n frame : ${frame.width.toFixed(0)} x ${frame.height.toFixed(0)}; } }如果你做的是只允许横屏的游戏LandscapeGuard更实用检测到竖屏就弹一个提示节点盖住画面import { _decorator, Component, Node, view } from cc; const { ccclass, property } _decorator; ccclass(LandscapeGuard) export class LandscapeGuard extends Component { property(Node) overlay: Node null; update() { if (!this.overlay) return; const frame view.getFrameSize(); this.overlay.active frame.width frame.height; } }4.4 跑通 Demo 的 5 分钟清单按下面顺序走一遍顺利的话真的只要 5 分钟新建 3.8.2 项目在项目设置 → 项目数据里把设计分辨率设为 720×1280。新建场景创建 Canvas勾选 Fit Width 和 Fit Height。在 Canvas 下按上面的节点树搭好 Bg、PortraitRoot、LandscapeRoot、InfoLabel。给 Bg 配一个纯色或星空 SpriteWidget 四边全对齐填 0。给 PortraitRoot 和 LandscapeRoot 挂 SafeArea 组件分别创建两套布局子节点。在 Canvas 上挂 OrientationAuto把两个 Root 分别拖到对应属性。运行预览用手拖动浏览器窗口改变宽高比观察两套布局切换再点预览工具栏的机型分辨率下拉选几个 16:9、19.5:9、21:9 的档位确认没有元素被切。浏览器预览确认没问题之后再用 Build 面板打一个 Android 或 iOS 包设好 Orientation 为 Auto真机旋转验证一遍。真机上的情况通常和浏览器有出入下一节讲怎么排查。5. 真机踩坑记录黑边、拉伸、错位的排查链路5.1 黑边/红边先分清是哪种策略导致的遇到屏幕边缘漏底色先看 Canvas 的 Fit 勾选。两个都不勾就是 SHOW_ALL边缘露出的区域是设计分辨率空间之外的空白这是策略本身的行为不是 bug。我之前见过有同事在这个状态下苦调半天背景图最后发现背景节点根本没铺满可见区域纯属策略选错了。排查方法打印view.getVisibleSize()对比屏幕比例和设计分辨率比例。如果 visible 的宽高比和设计分辨率不一致说明当前是非等比映射或留边状态这时候要么改 Canvas 勾选要么把背景节点做成 Widget 四边对齐且覆盖到 Canvas 外一截。我个人偏好 NO_BORDER 背景 Widget 贴满从根源上杜绝留边。5.2 元素被裁切visible size 比设计分辨率小这是只勾 Fit Height 但屏幕更细长的典型症状。设计分辨率 720×1280在 21:9 的竖屏机器上左右可显示的设计宽度可能只有 600 出头排在左右两侧的按钮直接被切。排查链路在 InfoLabel 上看到 visible 宽度明显小于 720基本就可以断定是宽度方向被裁。解决方向有两个一是把重要元素全部收进 Widget 的最小安全边距内保证即使最窄机型也不会切到二是换成 Fit Width Fit HeightNO_BORDER配合更宽的 UI 安全区。记住一个经验任何靠贴边定位的元素在窄屏机型上都有被裁的风险用 Widget 给的边距值要按最差机型算不是按设计稿算。5.3 旋转后 Widget 不刷新事件没有接住这个坑我踩过不止一次。场景里明明用了 Widget浏览器预览时拉窗口也正常但手机上从竖屏转到横屏某些节点还是按旧的屏幕比例待着位置全乱。原因多半是转发时机问题浏览器里两次 resize 事件之间会先触发 orientationchangeCocos 内部在这个时机更新 Canvas 和 Widget但如果你在页面级监听了 resize 再去改节点布局可能跑在 Cocos 更新之前布局又被覆盖回去。我的处理方式是统一走 Cocos 的screen.on(window-resize)不要自己额外挂 window 的 resize 监听除非你有非常特殊的逻辑。另外如果某些节点是代码 move 过的Widget 的自动对齐可能被覆盖旋转后需要自己重新设置widget.updateAlignment()或者重置节点的 position。给一个参考写法import { _decorator, Component, Widget } from cc; const { ccclass } _decorator; ccclass(ForceWidgetRefresh) export class ForceWidgetRefresh extends Component { refresh() { const widgets this.getComponentsInChildren(Widget); for (let i 0; i widgets.length; i) { widgets[i].updateAlignment(); } } }在新布局激活后调用一下能解决大部分明明加了对齐却不刷新的问题。5.4 刘海屏和折叠屏的特殊情况SafeArea 组件也不是万能。iPhone 上的刘海信息系统给得很规范Cocos 读起来比较准但安卓机型的挖孔位置千奇百怪有的在左上角有的在中间有的横屏时移到长边SafeArea 在不同厂商系统上的返回值并不统一。我见过华为、小米的机型在横屏时安全区返回异常导致按钮被推到屏幕外。折叠屏更要命屏幕开合本身就是一次尺寸剧变而且很多折叠屏在展开时会强制重新走一遍 Activity 重建流程直接导致场景重新加载。应对方式是真机测试矩阵里必须包含一台最常见的折叠屏主力机型至少覆盖展开/折叠两个形态代码里不要把任何持久化数据放在 UI 编辑器的临时变量里因为场景重建后这些值会丢。如果 SafeArea 的返回值在某个机型上不靠谱退路是自己读系统参数。原生端可以在 Android 工程里读WindowInsets在 iOS 工程里读safeAreaInsets通过 Cocos 的native桥接接口传给 TS 层。这一步不是入门内容但真遇到特定机型问题这是绕不开的路。5.5 各平台验证清单我每次交付多分辨率相关的版本都会按下面这张表过一遍省得反复被测试退回检查项浏览器模拟安卓真机iOS 真机16:9 屏无拉伸✓✓✓19.5:9 屏无黑边✓✓✓21:9 屏重要元素不被裁尽量视机型视机型顶部安全区不遮挡标题模拟器不准确✓✓底部手势条区域不挡按钮模拟器不准确✓✓竖屏转横屏布局切换正确✓✓✓转屏后 Widget 对齐正确✓✓✓折叠屏展开/闭合后正常无法模拟视机型无实际测试中我还有个习惯把VisibleDebug的 InfoLabel 常驻在屏幕上几分钟手动快速旋转设备看 visible 数据有没有瞬间跳变。数据异常通常比画面异常更早暴露问题排查起来速度快很多。最后补几句实操心得多分辨率适配这个事说到底是提前把最差机型想清楚的问题。不要在项目快上线了才开始适配那时候改设计分辨率、改 Widget 边距的成本会翻好几倍。我是从做休闲游戏开始养成习惯的新建项目第一天就把 Canvas 策略、安全区容器、调试用的 InfoLabel 全部搭好后续每个界面都在这个框架里开发后期基本不会遇到这个界面怎么又跑偏了的问题。另外一个小技巧项目里维护一个文档记录每一档 Build 对应的设计分辨率、Fit 策略和已验证的机型清单尤其是折叠屏和异形屏机型。团队里换人接手的时候这份记录比口头交代好用得多。多分辨率适配本身不难难的是让团队里每个人都按同一套规则开发这才是真正让5 分钟搞定适配不再只是一句口号的关键。
返回列表