with one click
cocos-creator-adaptation
做 Cocos Creator 多机型/多分辨率适配时使用。Canvas、Widget、安全区。
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
做 Cocos Creator 多机型/多分辨率适配时使用。Canvas、Widget、安全区。
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
Cocos Creator 用 AssetBundle 做分包/远程资源时使用。加载、释放、依赖、缓存。
优化 Cocos Creator 渲染性能时使用。合批、图集、动静分离、Label。
给 Cocos Creator 原生包做热更新时使用。version manifest、增量、校验、回滚。
写 Cocos Creator 动效/动画时使用。tween、Animation、Spine、性能与清理。
做 Cocos Creator 大量条目列表时使用。虚拟列表、节点复用。
写 Cocos Creator(TypeScript)时使用。组件、节点、prefab、事件、资源管理规范。
| name | cocos-creator-adaptation |
| description | 做 Cocos Creator 多机型/多分辨率适配时使用。Canvas、Widget、安全区。 |
| category | gamedev |
| tags | ["cocoscreator","适配","ui"] |
setDesignResolutionSize 却不清楚 fitWidth/fitHeight 该选哪个时。规则: 竖屏游戏设计分辨率用「宽固定」策略(ResolutionPolicy.FIXED_WIDTH,等价于 fitWidth),横屏游戏用「高固定」策略(FIXED_HEIGHT,等价于 fitHeight);在 onLoad 最早处或启动场景的 App.ts 里统一调用,不在各业务组件里重复设置。
为什么: 这是最高频犯错的地方。新手默认保持编辑器的 SHOW_ALL(黑边适配),在宽屏手机上两侧各出现一条黑边,玩家体验极差。AI 生成代码时经常写死 cc.view.setDesignResolutionSize(750, 1334, cc.ResolutionPolicy.SHOW_ALL)——这在 iPhone 8 比例下"看起来对",换到 18:9 或 20:9 的安卓机立刻穿帮。竖屏游戏应该固定宽度让高度自然延伸(上下内容按 Widget 锚定),这样无论多长的屏幕内容都能自适应撑满,不露黑边;横屏游戏则反过来固定高度。
怎么做:
cc.view.setDesignResolutionSize(750, 1334, cc.ResolutionPolicy.FIXED_WIDTH);cc.view.setDesignResolutionSize(1334, 750, cc.ResolutionPolicy.FIXED_HEIGHT);onLoad 里设置一次,场景切换后 cc.view 配置保持,不需要每个场景重设。规则: 所有 UI 节点(按钮、血条、对话框、提示文字)必须挂 Widget 组件并锚定到合适的边或居中;绝对坐标(position.x = 375)只允许出现在以父节点为参考系且父节点本身已正确适配的情况下。
为什么: 在 1080×2340 手机上绝对坐标看起来对,到 720×1600 上就整体偏移。AI 生成 UI 代码时习惯输出 this.node.setPosition(0, -500)——这在设计分辨率内是居中底部,但换机型后高度变了,-500 就不再是"底部附近"。更隐蔽的问题:场景切换或节点被动态 addChild 到另一个父节点后,绝对坐标失效但运行时无报错,只是 UI 错位。Widget 的「UpdateAlignment」会在节点激活时自动重算位置,是唯一正确的跨分辨率对齐方式。
怎么做:
node.addComponent(Widget) 并设置对应属性,不要只用 setPosition。规则: 在根 Canvas 下创建一个「安全区容器」节点,挂载 SafeArea 组件(Cocos Creator 3.x 内置),所有可能被刘海/挖孔/Home 条遮挡的 UI 放入该容器;背景图等装饰性节点放在容器外,允许延伸到边缘。
为什么: iPhone 14 Pro 的动态岛、安卓各厂商形态各异的挖孔摄像头、底部 Home Indicator——如果不处理安全区,玩家的返回按钮、血量数值、关键提示文字会直接被系统 UI 盖住,甚至无法点击。最常见的错误做法是手动给顶部 UI 加固定偏移 top = 88(iPhone X 刘海高度),这在其他机型上会多出一段空白,在新机型上又不够。SafeArea 组件会在运行时读取系统安全区域数据动态调整,是唯一跨机型正确的方案。
怎么做:
Node 命名为 SafeArea,大小设为 (100%, 100%),挂 Widget(全四边对齐)和 cc.SafeArea 组件。SafeArea 节点。SafeArea 容器外,让其撑满到屏幕物理边缘。规则: 全屏背景图用 Sprite 的 SizeMode 设为 CUSTOM 并配合 Widget 全拉伸,Trim 关闭,让图片裁切填满屏幕(类似 CSS background-size: cover);核心游戏内容区(如战斗 HUD、地图区域)用统一的「安全内容节点」加等比缩放,避免拉伸变形。
为什么: 最常见的丑陋问题:背景图在 18:9 手机上宽高比正常,到平板的 4:3 上图片被拉宽变胖,角色脸型都变了。反过来,内容区如果也用全拉伸,按钮会被拉成椭圆。背景和内容的适配策略必须分开:背景允许裁切(多出的部分看不见无所谓),内容必须保持宽高比只能等比缩放(宁可两侧有一点间距,也不能变形)。
怎么做:
Sprite.SizeMode = CUSTOM,ContentSize 跟随父节点,让图片裁切填满。Widget 锁定宽或高(如竖屏锁宽),另一维度自动跟随,内部子节点用 Widget 相对于此容器定位。Math.min(scaleX, scaleY) 做等比缩放,保证不变形。规则: 每次调整适配逻辑后,必须在至少三种宽高比下验证:16:9(主流)、18:9/20:9(长屏安卓)、4:3(平板/iPad);发布前在真机上走一遍关键 UI 的可见性和可点击性检查。
为什么: Creator 编辑器的 GameView 预览窗口默认固定分辨率,调宽高看起来没问题,但实际运行时引擎在真机上的适配行为与预览有细微差异(尤其是安全区、原生输入框位置)。AI 生成的适配代码只会被作者在某一固定宽高比下测试,问题在另一个宽高比下才暴露。平板的 4:3 宽高比是最容易暴露「固定坐标 UI 超出屏幕范围」的机型。
怎么做:
750×1334(16:9)、750×1624(19.5:9)、1024×768(4:3)。// 反例 — SHOW_ALL 策略 + 绝对坐标 + 无安全区处理
import { _decorator, Component, view, ResolutionPolicy, Node } from 'cc';
const { ccclass } = _decorator;
@ccclass('GameInit')
export class GameInit extends Component {
onLoad() {
// ❌ SHOW_ALL 在长屏安卓上两侧出现黑边
view.setDesignResolutionSize(750, 1334, ResolutionPolicy.SHOW_ALL);
}
}
// UI 布局代码——另一个组件
@ccclass('MainHUD')
export class MainHUD extends Component {
@property(Node) backBtn: Node = null!;
@property(Node) scoreLabel: Node = null!;
onLoad() {
// ❌ 写死绝对坐标,换机型/分辨率立刻错位
this.backBtn.setPosition(-340, 580);
this.scoreLabel.setPosition(0, 560);
// ❌ 没有处理安全区,刘海屏上返回按钮被遮挡无法点击
}
}
// 正例 — 竖屏用 FIXED_WIDTH + Widget 锚定 + SafeArea 容器
import { _decorator, Component, view, ResolutionPolicy } from 'cc';
const { ccclass } = _decorator;
@ccclass('GameInit')
export class GameInit extends Component {
onLoad() {
// ✅ 竖屏固定宽度,高度自适应,不露黑边
view.setDesignResolutionSize(750, 1334, ResolutionPolicy.FIXED_WIDTH);
}
}
// 正例——编辑器内 SafeArea 容器 + Widget 配置(伪代码描述节点结构)
Canvas
└─ SafeAreaContainer ← 挂 SafeArea 组件 + Widget(L/R/T/B=0)
├─ TopBar ← Widget: Top=0, Left=0, Right=0, Height=固定
│ ├─ BackBtn ← Widget: Top=20, Left=20 (相对 TopBar)
│ └─ ScoreLabel ← Widget: HCenter=0, VCenter=0
└─ BottomBar ← Widget: Bottom=0, Left=0, Right=0, Height=固定
└─ Background ← Widget(L/R/T/B=0) + Sprite CUSTOM size(允许裁切)
// 反例 — 背景图不做适配,内容等比问题未处理
@ccclass('BgController')
export class BgController extends Component {
@property(Sprite) bgSprite: Sprite = null!;
onLoad() {
// ❌ SizeMode 保持 TRIMMED,背景在平板上宽高比失真变胖
// ❌ 没有 Widget,在长屏手机上背景不够高,露出底部空白
}
}
// 正例 — 背景图裁切填满 + Widget 全拉伸
import { _decorator, Component, Sprite, Widget, UITransform } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('BgController')
export class BgController extends Component {
@property(Sprite) bgSprite: Sprite = null!;
onLoad() {
// ✅ Widget 全四边对齐,背景随屏幕尺寸撑满
const widget = this.bgSprite.node.getComponent(Widget)!;
widget.isAlignLeft = true; widget.left = 0;
widget.isAlignRight = true; widget.right = 0;
widget.isAlignTop = true; widget.top = 0;
widget.isAlignBottom = true; widget.bottom = 0;
// ✅ SizeMode CUSTOM,UITransform 跟随父节点,图片裁切填满不变形
this.bgSprite.sizeMode = Sprite.SizeMode.CUSTOM;
// 编辑器里勾掉 Trim,让图片裁切而非拉伸
}
}
setDesignResolutionSize 的第三个参数:竖屏用 FIXED_WIDTH,横屏用 FIXED_HEIGHT,没有使用 SHOW_ALL。Widget 组件,没有通过 setPosition 写死绝对坐标。SafeArea 组件的容器内。CUSTOM 尺寸,不依赖原始图片宽高比。