cocosCreator笔记 之Spine简单使用,动态加载

版本: 3.4.0

参考:

Spine 骨骼动画资源

Spine Skeleton组件

cocosLua 之 骨骼动画


简介


使用spine动画,cocosCreator目前支持的版本:

creator版本spine版本
V3.0 及以上v3.8(原生平台不支持特定版本 v3.8.75)
v2.3 及以上v3.8
v2.2v3.7
v2.0.8~v2.1v3.6
v2.0.7 及以下v2.5

spine骨骼动画所需资源主要有如下三种:

  • .png 动画图片相关
  • .txt/.atlas 图集配置数据相关
  • .json/.skel 骨骼数据配置相关

spine骨骼动画主要组成部分:

  • bones 骨骼相关,基本组成元素,存在父子关系;每个骨骼可关联多个slot相关
  • slots 插槽相关, 主要用于关联多个attachment相关
  • attachment 附件相关, 有Mesh, BoundingBox, SkinnedMesh等不同类型
  • skins皮肤相关
  • animations 动画相关
  • ik

在cocosCreator中使用spine动画,官方封装的组件是sp.Skeleton


sp.Skeleton组件的使用


通过编译器添加spine动画,大概步骤:

  • 层级管理器创建一个空节点,假设命名为spine_node
  • spine_node属性检查器中,添加组件,搜索skeleton添加进来
  • 可把UITransform的锚点修改为(0.5, 0)

请添加图片描述

注意: spine骨骼动画在CocosCreator中的组件类型是sp.Skeleton,不是spine。
如果在代码中通过 @property 使用,节点可通过getComponent(sp.Skeleton)获取。

export class DebugLayer extends Component {
  @property(Node) 
  spineNode: Node = null;
  
  private _spine: sp.Skeleton = null;
  onLoad() {
    this._spine = this.spineNode.getComponet(sp.Skeleton);
  }
  
  onEnable() {
    // 使用Node类型,可以添加对spine动画的触摸事件
    this.spineNode.on(Node.EventType.TOUCH_END, this._touchSpineEvent, this);
  }
  
  private _touchSpineEvent() {
    console.log("you touch spine");
  }
}

cocosCreator通过Skeleton对spine骨骼动画封装了很多方法, 常用属性或接口有:

属性接口返回类型说明
loopboolean是否循环播放
pausedboolean当前骨骼动画是否暂停
animationstring当前播放的动画名称
timeScalenumber设置动画播放速度,数值越大,速度越快
debugSlotsboolean是否显示slot的测试信息
debugBonesboolean是否显示bone的测试信息
debugMeshboolean是否显示mesh的测试信息
useTintboolean是否启用染色效果
setSkin()void设置皮肤,比如切换衣服
setAttachment()void设置附件,比如切换武器
setMix()void设置两个动画的混合时间,用于优化动画之间切换不连贯
setAnimation()TrackEntry设置当前动画,不管前面是否播放动画,直接停止,然后播放设置的动画
addAnimation()TrackEntry添加动画,当前的动画单次播放结束后,开始播放
setToSetupPose()void还原到起始动作, 它主要用于处理上个动作留下的残影效果
findBone()spine.Bone根据骨骼名字获取骨骼信息
findSlot()spine.Slot根据关节名字获取关节信息
setStartListener()void事件回调, 设置开始播放动画的事件监听
setInterruptListener()void事件回调, 设置动画被打断的事件监听
setEndListener()void事件回调, 设置动画播放完后的事件监听
setDisposeListener()void事件回调, 设置动画将被销毁的事件监听
setCompleteListener()void事件回调, 设置播放一次循环结束后的事件监听
setEventListener()void事件回调, 设置动画播放过程中帧事件的监听

简单的示例:

export class UI_SpineLayer extends Component {
  @property(sp.Skeleton)
  spine: sp.Skeleton = null!;		\
  
  onLoad() {
    // 设置播放速度
    this.spine.timeScale = 0.6;
    // 设置两个动画之间的混合时间
    this.spine.setMix("walk", "run", 0.2);
    // 设置当前动画播放, trackIndex一般默认0即可
    this.spine.setAnimation(0, "walk", true);
    // 设置当前皮肤
    this.spine.setSkin("boy");
    // spine动画单次循环结束回调相关
    this.spine.setCompleteListener((trackEntry) => {
      let track = trackEntry.trackIndex;
      let aniName = trackEntry.animation ? trackEntry.animation.name : "";
      let loopCount = Math.floor(trackEntry.trackTime/trackEntry.animationEnd);
      if (aniName === "walk") {
        this.spine.timeScale = 1;
        this.spine.setToSetupPose();
        this.spine.setAnimation(trackIndex, "run", true);
      }
    });
  }
  
  public ChangeSkinEvent() {
    this.spine.setSkin("girl");		// 更换皮肤
  }
}

spine动画动态加载


在实际的项目中开发,spine动画动态加载是不可避免的, 这里提供一个简单的封装接口:

public loadSpine(spineNode: Node, resUrl: string, skinName: string = "default", aniName: string = "default", isLoop: boolean = true) {
    if (!spineNode || !spineNode.isValid) {
        console.error("loadSpine node null!!!");
        return;
    }
    spineNode.active = false;

    // 检测能否获取到已缓存的资源
    let spine = spineNode.getComponent(sp.Skeleton);
    let skeletonData: sp.SkeletonData = resources.get(resUrl);
    if (skeletonData) {
        spineNode.active = true;
        spine.skeletonData = skeletonData;
        spine.setSkin(aniName);
        spine.setAnimation(0, aniName, isLoop);
        // spineNode.active = true;    // Error
        return;
    }

    resources.load(resUrl, sp.SkeletonData, (err: Error, sd: sp.SkeletonData) => {
        if (err) {
            return console.error(err.message);
        } 
        // 动态加载为异步,因此增加下安全判定
        if (spineNode && spineNode.isValid) {
            spineNode.active = true;
            spine!.skeletonData = skeletonData;
            spine!.setSkin(aniName);
            spine!.setAnimation(0, aniName, isLoop);
            // spineNode.active = true;    // Error
        }
    });
}

注: 关于spineNode的 active 不可放在最后面,否则动画能够正常加载,但不能正常播放。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鹤九日

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值