Im using 2.4.10 creator and i want to use my spine animations to use a single shared atlas. currently, creator uses one atlas for each spine animation. What would be the best way to support this?
spineDemo.zip (2.9 MB)
You can learn the method in this project to swap Spine by reading SpriteFrame from SpriteAtlas.
This method is currently only supported on Web.
const {ccclass, property} = cc._decorator;
@ccclass
export class SpineHelperCmp extends cc.Component {
// spine组件
private spineCmp: sp.Skeleton = null;
// 加载接口
protected onLoad(): void {
this.spineCmp = this.node.getComponent(sp.Skeleton);
}
// 创建区域
private createRegion(tex2d: cc.Texture2D, rotate: boolean, x: number, y: number, width: number, height: number) {
// @ts-ignore
const skeTexture = new sp.SkeletonTexture({width: width, height: height} as ImageBitmap);
skeTexture.setRealTexture(tex2d);
const region = new sp.spine.TextureAtlasRegion();
region.width = width;
region.height = height;
region.originalWidth = width;
region.originalHeight = height;
// 读取图集代码
const bigTextureWidth = tex2d.width;
const bigTextureHeight = tex2d.height;
region.rotate = rotate;
if (rotate) {
region.u = (x + height) / bigTextureWidth;
region.v = (y + width) / bigTextureHeight;
region.u2 = x / bigTextureWidth;
region.v2 = y / bigTextureHeight;
} else {
region.u = x / bigTextureWidth;
region.v = y / bigTextureHeight;
region.u2 = (x + width) / bigTextureWidth;
region.v2 = (y + height) / bigTextureHeight;
}
region.texture = skeTexture;
region.renderObject = region;
return region
}
// 获取卡槽的slot的附件Attachment
private getSlotAttachment(slotName: string) {
if (!this.spineCmp) {
console.log('spine is null');
return null;
}
let slot = this.spineCmp.findSlot(slotName);
if (slot === null) {
console.log(`slot ${slotName} is null`);
return null;
}
let attachment = slot.getAttachment();
if (attachment === null) {
console.log('getAttachment is null');
return null;
}
return attachment;
}
/**
* 播放spine动画
*
* @param {string} actionName 动作名
* @param {bool} loop 是否循环
* @param {number} trackIndex 播放轨道
*/
public playAnim(actionName: string, loop: boolean = false, trackIndex: number = 0) {
if (!this.spineCmp) return;
this.spineCmp.setAnimation(trackIndex, actionName, loop);
}
/**
* 插槽Slot换肤
*
* @param {string} slotName 插槽名称
* @param {string} imgPath 图片地址
*/
public async modifyAttachment(slotName: string, spriteFrame: cc.SpriteFrame) {
let attachment = this.getSlotAttachment(slotName);
if (attachment == null) {
console.log('attachment is null');
return;
}
const rect = spriteFrame.getRect();
const x = rect.x;
const y = rect.y;
const width = rect.width;
const height = rect.height;
const rotate = spriteFrame.isRotated();
let bigTexture = spriteFrame.getTexture();
// @ts-ignore
const region = this.createRegion(bigTexture, rotate, x, y, width, height, attachment.region);
attachment.region = region;
attachment.width = width;
attachment.height = height;
if (attachment instanceof sp.spine.MeshAttachment) {
attachment.updateUVs();
}
else{
attachment.setRegion(region);
attachment.updateOffset();
}
}
}
cool, this is useful during runtime @zzf_Cocos . but i was hoping the texture can be assigned while in the editor. I noticed that the spine file asset has a atlas texture property
but the texture is automatically set by the editor with the atlas with the same filename as spine animation file.

Is it possible to extend the spine extension in the cocos engine to make this customizeble? (sorry i should have said this at the beginning)
The Cocos Creator 2.x version editor currently cannot edit Spine.