
其实这部分和Oops没什么直接关系但是做creator小游戏肯定用的到。这里直接写入这个系列记录一下方便以后查找。方式一内置【自动图集 Auto-Atlas】不用第三方工具开发用碎图、打包自动合图首选小项目。步骤资源归类把要打包的零散 png 全部放到同一个文件夹如res/ui_icon右键文件夹空白处 → 新建 →自动图集配置auto-atlas.pacpac 放在这个图片目录里规则当前文件夹 所有子文件夹里所有图片构建打包时自动合并成图集子目录如果单独放 pac该子目录不再被上层 pac 打包属性面板配置选中 pac 文件表格配置项推荐值说明最大宽 / 高2048/2048主流平台上限别超 4096间距2防渲染黑边扩边1px解决纹理接缝黑线允许旋转勾选节省图集空间预览点属性面板【预览】查看Packed Textures成功打包、Unpacked Textures过大 / 异常无法打包Cocos Creator生效时机编辑器里依旧使用零散小图构建发布项目时引擎自动合成大图图集打包后自动合并 drawcallCocos Creator优点改图不用重新打图集直接替换碎图即可缺点编辑器预览还是散图调试看不到合图效果大型项目图集不可控笔者注这里虽然说是可以打包成2048的但是我在微信和抖音小游戏开发中一直使用的是1024甚至有时候极端一些会使用512的图集。建议通常还是文件夹分的仔细一些。方式二TexturePacker 手动打包图集精准控图集中大型项目 / 需要编辑器实时合图步骤1、TP 打包设置关键导出 Cocos2d-x 格式 plistpngTP 拖入所有零散小图右侧框架选cocos2d-x3.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_iconplistpng 同目录资源名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(); // 资源计数防止被自动释放 }) }) } }复用已加载 bundleconst bundle assetManager.getBundle(ui_bundle);非空直接bundle.load()三、【远程 Bundle 加载图集】http/https 服务器托管 bundle传完整 URL1、部署规则远程 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 名称不用全 URLassetManager.loadBundle(ui_bundle,cb)引擎自动拼接配置域名 remote / 包名四、Promise 封装推荐async/await 写法// 封装通用加载 async function loadBundleAtlas(bundleSrc:string, atlasPath:string):PromiseSpriteAtlas{ 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 端服务器配置 CORSnginx 添加跨域头资源释放不用时bundle.releaseAll();或atlas.decRef()减少引用自动图集 Auto-Atlas不能单独打包进 bundle必须 TP 手动导出 plist 图集才能 bundle 加载