如何用Spritesheet替代原生图集加载到Spine骨骼(PixiJS v7.3/pixi-spine v4.0.4)
PixiJS v7.3 + pixi-spine v4.0.4 自定义Spritesheet加载方案
针对旧版AtlasAttachmentLoader失效的问题,核心解决思路是自定义适配Pixi Spritesheet的AttachmentLoader,直接复用已加载的Spritesheet纹理资源,无需依赖原生Spine图集。
步骤1:提前加载资源
确保Pixi的Loader已完成Spine JSON和目标Spritesheet的加载,纹理资源全部就绪:
import { Loader } from 'pixi.js'; const loader = new Loader(); // 加载TexturePacker生成的Spritesheet JSON loader.add('game-spritesheet', './assets/spritesheet.json'); // 加载Spine骨骼JSON loader.add('player-spine', './assets/player-spine.json'); loader.load((loader, resources) => { // 资源加载完成后执行后续逻辑 initSpineWithSpritesheet(resources['game-spritesheet'].spritesheet, resources['player-spine'].data); });
步骤2:实现自定义AttachmentLoader
继承pixi-spine的BaseAttachmentLoader,重写附件创建方法,从Spritesheet中匹配对应纹理:
import { BaseAttachmentLoader } from '@pixi-spine/base'; import { Spritesheet } from 'pixi.js'; class SpritesheetAttachmentLoader extends BaseAttachmentLoader { constructor(private spritesheet: Spritesheet) { super(); } // 处理普通区域附件 newRegionAttachment(skin, name, path) { const texture = this.spritesheet.textures[path]; if (!texture) throw new Error(`Missing texture for path: ${path}`); const attachment = super.newRegionAttachment(skin, name, path); // 将Spritesheet纹理绑定到附件 attachment.renderObject = texture; return attachment; } // 按需处理Mesh附件(若项目使用Mesh骨骼) newMeshAttachment(skin, name, path) { const texture = this.spritesheet.textures[path]; if (!texture) throw new Error(`Missing texture for path: ${path}`); const attachment = super.newMeshAttachment(skin, name, path); attachment.renderObject = texture; return attachment; } // 其他类型附件(如BoundingBox、Path等)按需重写,无需处理可继承父类默认实现 }
步骤3:解析骨骼并创建Spine实例
使用自定义Loader解析Spine JSON,生成可渲染的Spine精灵:
import { SkeletonJson, Skeleton, AnimationStateData, AnimationState } from '@pixi-spine/base'; import { Spine } from '@pixi-spine/pixi7'; function initSpineWithSpritesheet(spritesheet, spineJsonData) { // 初始化自定义Loader const attachmentLoader = new SpritesheetAttachmentLoader(spritesheet); const skeletonJson = new SkeletonJson(attachmentLoader); // 解析骨骼数据 const skeletonData = skeletonJson.readSkeletonData(spineJsonData); // 创建骨骼与动画控制器 const skeleton = new Skeleton(skeletonData); const animationStateData = new AnimationStateData(skeletonData); const animationState = new AnimationState(animationStateData); // 创建Spine精灵并添加到舞台 const spineSprite = new Spine(skeleton); spineSprite.position.set(400, 300); // 设置显示位置 app.stage.addChild(spineSprite); // 播放循环动画 animationState.setAnimation(0, 'idle', true); // 帧更新时同步动画状态 app.ticker.add(() => { animationState.update(1/60); animationState.apply(skeleton); skeleton.updateWorldTransform(); }); }
关键注意事项
- 纹理Key匹配:确保Spritesheet中每个纹理的key与Spine JSON里附件的
path字段完全一致,否则会抛出找不到纹理的错误。 - 附件类型覆盖:若项目使用了Mesh、Clipping等特殊附件,必须对应重写AttachmentLoader中的创建方法,否则无法正常渲染。
- 加载顺序:必须等待Spritesheet加载完成后再解析Spine JSON,避免纹理未就绪导致的渲染异常。
内容的提问来源于stack exchange,提问作者el-greko
相关产品推荐
相关产品推荐

