龙骨动画比序列帧 优点好太多了, CocosCreator 提供了很好的支持:
我们就用 龙骨软件自带的动画做一个demo 给大家介绍下:
1. 第一步 肯定是导出资源
我这边是按照目录进度的加载, 两个文件夹,对应两个英雄的动画资源
2. 第二步代码动态加载需要的英雄动画资源
import { _decorator, Component, Node, SpriteAtlas, resources, Asset } from 'cc'; const { ccclass, property } = _decorator; export class DragonBonesManager { public static async loadDragonBonesByName(name: string) { console.log("loadDragonBonesByName---:", name) return await new Promise<Array<Asset>>((resolve) => { resources.loadDir(`dragonAnim/heros/${name}`, Asset, null, (err, assets) => { if (err) { console.log(`资源加载失败 ${name}:`, err); } else { resolve(assets); } }) }); } }
3. 第三步 实例化动画
public async initDragonBones(heroName: string) { let res: Array<any> = await DragonBonesManager.loadDragonBonesByName(heroName); // 第一种 编辑器可以运行显示 打包不显示 (原因是应为 返回来的数据 索引会变化) // this.dragonBones.dragonAsset = res[0] as dragonBones.DragonBonesAsset; // this.dragonBones.dragonAtlasAsset = res[2] as dragonBones.DragonBonesAtlasAsset; // this.dragonBones.armatureName = JSON.parse(this.dragonBones!.dragonAsset?.dragonBonesJson!).armature[0].name; // 第二种 方案区分 debug 和 release // if( DEBUG ){ // this.dragonBones.dragonAsset = res[0] as dragonBones.DragonBonesAsset; // this.dragonBones.dragonAtlasAsset = res[2] as dragonBones.DragonBonesAtlasAsset; // this.dragonBones.armatureName = JSON.parse(this.dragonBones!.dragonAsset?.dragonBonesJson!).armature[0].name; // }else{ // this.dragonBones.dragonAsset = res[4] as dragonBones.DragonBonesAsset; // this.dragonBones.dragonAtlasAsset = res[0] as dragonBones.DragonBonesAtlasAsset; // this.dragonBones.armatureName = JSON.parse(this.dragonBones!.dragonAsset?.dragonBonesJson!).armature[0].name; // } // 第三中 最大兼容方式 直接判断类型 for (let i = 0; i < res.length; i++) { if (res[i] instanceof dragonBones.DragonBonesAsset) { this.dragonBones.dragonAsset = res[i] as dragonBones.DragonBonesAsset; } else if (res[i] instanceof dragonBones.DragonBonesAtlasAsset) { this.dragonBones.dragonAtlasAsset = res[i] as dragonBones.DragonBonesAtlasAsset; } } this.dragonBones.armatureName = JSON.parse(this.dragonBones!.dragonAsset?.dragonBonesJson!).armature[0].name; this.dragonBones.playAnimation("idle", 0); }
完整脚本:
import { _decorator, Component, Node, dragonBones, Asset } from 'cc'; import { DEBUG } from 'cc/env'; import { DragonBonesManager } from '../../../../common/utils/DragonBonesHelper'; const { ccclass, property } = _decorator; @ccclass('HeroSelf') export class HeroSelf extends Component { @property(dragonBones.ArmatureDisplay) private dragonBones: dragonBones.ArmatureDisplay; // start() { // this.dragonBones.dragonAsset // this.dragonBones.dragonAtlasAsset // } // update(deltaTime: number) { // } public async initDragonBones(heroName: string) { let res: Array<any> = await DragonBonesManager.loadDragonBonesByName(heroName); // 第一种 编辑器可以运行显示 打包不显示 (原因是应为 返回来的数据 索引会变化) // this.dragonBones.dragonAsset = res[0] as dragonBones.DragonBonesAsset; // this.dragonBones.dragonAtlasAsset = res[2] as dragonBones.DragonBonesAtlasAsset; // this.dragonBones.armatureName = JSON.parse(this.dragonBones!.dragonAsset?.dragonBonesJson!).armature[0].name; // 第二种 方案区分 debug 和 release // if( DEBUG ){ // this.dragonBones.dragonAsset = res[0] as dragonBones.DragonBonesAsset; // this.dragonBones.dragonAtlasAsset = res[2] as dragonBones.DragonBonesAtlasAsset; // this.dragonBones.armatureName = JSON.parse(this.dragonBones!.dragonAsset?.dragonBonesJson!).armature[0].name; // }else{ // this.dragonBones.dragonAsset = res[4] as dragonBones.DragonBonesAsset; // this.dragonBones.dragonAtlasAsset = res[0] as dragonBones.DragonBonesAtlasAsset; // this.dragonBones.armatureName = JSON.parse(this.dragonBones!.dragonAsset?.dragonBonesJson!).armature[0].name; // } // 第三中 最大兼容方式 直接判断类型 for (let i = 0; i < res.length; i++) { if (res[i] instanceof dragonBones.DragonBonesAsset) { this.dragonBones.dragonAsset = res[i] as dragonBones.DragonBonesAsset; } else if (res[i] instanceof dragonBones.DragonBonesAtlasAsset) { this.dragonBones.dragonAtlasAsset = res[i] as dragonBones.DragonBonesAtlasAsset; } } this.dragonBones.enabled = true; this.dragonBones.dragonAsset.addRef() this.dragonBones.dragonAtlasAsset.addRef() this.dragonBones.armatureName = JSON.parse(this.dragonBones!.dragonAsset?.dragonBonesJson!).armature[0].name; this.dragonBones.playAnimation("idle", 0); } /** * 卸载龙骨资源 */ public decRefDragonBones() { this.dragonBones.enabled = false; if (this.dragonBones.dragonAsset) { this.dragonBones.dragonAsset.decRef(); } if (this.dragonBones.dragonAtlasAsset) { this.dragonBones.dragonAtlasAsset.decRef(); } } public dragonBonesIdle() { this.dragonBones.playAnimation("idle", 0); } public dragonBonesAttack() { this.dragonBones.playAnimation("attack", 1); } public dragonBonesUnderAttack() { this.dragonBones.playAnimation("underAttack", 1); } }
这里有个小插曲:动态加载 发布不显示 ,后开发现下 动态加载出来的 数组 索引会发生变化; 我这里采用最大兼容的方案三