Oops Framework-5-GUI资源的图集打包方式
其实这部分和Oops没什么直接关系,但是做creator小游戏肯定用的到。这里直接写入这个系列记录一下,方便以后查找。
方式一:内置【自动图集 Auto-Atlas】
不用第三方工具,开发用碎图、打包自动合图,首选小项目。
步骤
- 资源归类:把要打包的零散 png 全部放到同一个文件夹(如
res/ui_icon) - 右键文件夹空白处 → 新建 →自动图集配置(auto-atlas.pac),pac 放在这个图片目录里
规则:当前文件夹 + 所有子文件夹里所有图片,构建打包时自动合并成图集;子目录如果单独放 pac,该子目录不再被上层 pac 打包
- 属性面板配置(选中 pac 文件)
表格
配置项 推荐值 说明 最大宽 / 高 2048/2048 主流平台上限,别超 4096 间距 2 防渲染黑边 扩边 1px 解决纹理接缝黑线 允许旋转 勾选 节省图集空间 - 预览:点属性面板【预览】,查看
Packed Textures(成功打包)、Unpacked Textures(过大 / 异常无法打包)Cocos Creator - 生效时机:编辑器里依旧使用零散小图;构建发布项目时引擎自动合成大图图集,打包后自动合并 drawcallCocos Creator
优点:改图不用重新打图集,直接替换碎图即可;缺点:编辑器预览还是散图,调试看不到合图效果,大型项目图集不可控
笔者注
这里虽然说是可以打包成2048的,但是我在微信和抖音小游戏开发中一直使用的是1024甚至有时候极端一些会使用512的图集。建议通常还是文件夹分的仔细一些。
方式二:TexturePacker 手动打包图集
精准控图集,中大型项目 / 需要编辑器实时合图
步骤
1、TP 打包设置
(关键:导出 Cocos2d-x 格式 plist+png)
- TP 拖入所有零散小图
- 右侧框架选:cocos2d-x(3.x Creator 必须 TP5 + 版本,旧版 4.x 导出 plist 不兼容)Cocos Creator
- 关闭多余裁剪、设置边距 2px,点击
Publish sprite sheet,生成同名 .png + .plist两个文件 - 两个文件一起拖拽进 Creator 资源面板,自动生成SpriteAtlas 图集资源
2、Creator 使用图集
- 场景 Sprite 组件:Atlas 选导入的 plist 图集,SpriteFrame 下拉直接选图集中小图
- TS 代码动态加载:
import { resources, SpriteAtlas, Sprite } from 'cc'; resources.load("文件夹名/图集名", SpriteAtlas, (err, atlas)=>{ const frame = atlas.getSpriteFrame("图片原名"); this.node.getComponent(Sprite).spriteFrame = frame; })优点:编辑器实时合图、精准控制哪些图进同一张图集,DrawCall 调试直观;缺点:改素材需要重新用 TP 导出图集,替换 plist/png
笔者注
- 图集尺寸规范:单图集≤2048×2048,尽量使用1024以下,微信小游戏 / 低端机避免 大图
- 分类打包:UI 图标、角色、特效分开文件夹分图集,不要全图打进一张大图
- 自动图集避坑:单张碎图尺寸>pac 最大宽高会打包失败,出现在 Unpacked 列表
用Bundle 方式加载图集
一、前置配置
- 本地 Bundle:文件夹不勾选【配置为远程包】,构建后在
build/xxx/assets/包名目录 - 远程 Bundle:文件夹勾选【配置为远程包】,构建后在
build/xxx/remote/包名,把整个包文件夹丢到 http 服务器(nginx/node 静态服务) - 图集存放:Bundle 目录下
atlas/ui_icon(plist+png 同目录,资源名ui_icon)
二、【本地 Bundle 加载图集】(包内置在安装包内,传 bundle 名字符串)
代码(TS,组件内使用)
import { _decorator, Component, assetManager, SpriteAtlas, Sprite, find } from 'cc'; const { ccclass, property } = _decorator; @ccclass('LoadAtlas') export class LoadAtlas extends Component { start() { const spr = find("Canvas/TestSprite")!.getComponent(Sprite)!; // 1. 传入Bundle名称(配置Bundle时的名字) assetManager.loadBundle("ui_bundle", (err, bundle) => { if(err) return console.error("bundle加载失败",err); // 2. bundle内加载图集资源,路径=bundle内相对路径,不加后缀 bundle.load("atlas/ui_icon", SpriteAtlas, (e, atlas:SpriteAtlas)=>{ if(e) return console.error("图集加载失败",e); // 3. 从图集取小图,文件名=TP里原始图片名 const frame = atlas.getSpriteFrame("btn_ok"); spr.spriteFrame = frame; atlas.addRef(); // 资源计数,防止被自动释放 }) }) } }- 复用已加载 bundle:
const bundle = assetManager.getBundle("ui_bundle");,非空直接bundle.load()
三、【远程 Bundle 加载图集】(http/https 服务器托管 bundle,传完整 URL)
1、部署规则
远程 bundle 完整地址示例:http://127.0.0.1:8080/res/ui_bundle
服务器目录:
/res/ui_bundle/config.json、index.js、xxx.png(构建 remote 里整个文件夹原样上传)
2、加载代码
start() { const spr = find("Canvas/TestSprite")!.getComponent(Sprite)!; // 远程填完整bundle文件夹URL const bundleUrl = "http://127.0.0.1:8080/res/ui_bundle"; assetManager.loadBundle(bundleUrl, (err, bundle) => { if(err) return console.error("远程bundle下载失败",err); // 和本地一致,加载图集 bundle.load("atlas/ui_icon", SpriteAtlas, (e, atlas:SpriteAtlas)=>{ const frame = atlas.getSpriteFrame("btn_ok"); spr.spriteFrame = frame; atlas.addRef(); }) }) }3、小游戏远程特殊配置(微信 / 抖音小游戏)
- 构建发布面板→资源服务器地址填域名:
https://xxx.com/res/remote/ - 代码直接写 bundle 名称,不用全 URL:
assetManager.loadBundle("ui_bundle",cb),引擎自动拼接配置域名 + remote / 包名
四、Promise 封装(推荐,async/await 写法)
// 封装通用加载 async function loadBundleAtlas(bundleSrc:string, atlasPath:string):Promise<SpriteAtlas>{ return new Promise((resolve,reject)=>{ assetManager.loadBundle(bundleSrc,(err,bundle)=>{ if(err) return reject(err); bundle.load(atlasPath,SpriteAtlas,(e,atlas)=>{ e?reject(e):resolve(atlas); }) }) }) } // 使用 async testLoad(){ // 本地:传包名 // const atlas = await loadBundleAtlas("ui_bundle","atlas/ui_icon"); // 远程:传url const atlas = await loadBundleAtlas("http://127.0.0.1:8080/res/ui_bundle","atlas/ui_icon"); this.node.getComponent(Sprite)!.spriteFrame = atlas.getSpriteFrame("btn_ok"); }笔者注
- 资源路径:
bundle.load路径不带.png/.plist 后缀,资源清单 config.json 无后缀名记录 - 远程跨域:web 端服务器配置 CORS,nginx 添加跨域头
- 资源释放:不用时
bundle.releaseAll();,或atlas.decRef()减少引用 - 自动图集 Auto-Atlas:不能单独打包进 bundle,必须 TP 手动导出 plist 图集才能 bundle 加载
