支持spine4.3

This commit is contained in:
tianmo committed 2026-09-02 13:53:12 +08:00
1 parent 63e4f61631
commit 0656684a92
206 files changed
+100597 -1320

No files matched your search

+16 -13
View File
@@ -1,11 +1,11 @@
import { Container } from 'pixi.js'
import { Spine } from '@esotericsoftware/spine-pixi-v7'
import { getSpineAsset } from './spineAssetRegistry'
import type { SpineSceneObject } from './spineTypes'
interface RuntimeEntry {
root: Container
spine: Spine
spine: any
runtimeVersion: '4.2' | '4.3'
assetVersion: number
animation: string
}
@@ -45,12 +45,13 @@ export class SpineRuntimeLayer {
entry.root.destroy({ children: true })
}
const root = new Container()
const spine = new Spine({ skeletonData: asset.skeletonData, autoUpdate: false, darkTint: false })
const spine = new asset.SpineClass({ skeletonData: asset.skeletonData, autoUpdate: false, darkTint: false })
if (asset.skeletonData.defaultSkin) spine.skeleton.setSkin(asset.skeletonData.defaultSkin)
spine.skeleton.setSlotsToSetupPose()
if (asset.runtimeVersion === '4.3') spine.skeleton.setupPoseSlots()
else spine.skeleton.setSlotsToSetupPose()
root.addChild(spine)
this.container.addChild(root)
entry = { root, spine, assetVersion: object.assetVersion, animation: '' }
entry = { root, spine, runtimeVersion: asset.runtimeVersion, assetVersion: object.assetVersion, animation: '' }
this.entries.set(object.id, entry)
}
if (!entry) continue
@@ -66,12 +67,13 @@ export class SpineRuntimeLayer {
if (entry.animation !== object.selectedAnimation) {
entry.animation = object.selectedAnimation
spine.skeleton.setToSetupPose()
if (entry.runtimeVersion === '4.3') spine.skeleton.setupPose()
else spine.skeleton.setToSetupPose()
spine.state.clearTracks()
// 编辑器时间轴负责整体循环;单个 Spine 动画自身只播放一次并停在末帧。
if (entry.animation) spine.state.setAnimation(0, entry.animation, false)
}
const track = spine.state.getCurrent(0)
const track = entry.runtimeVersion === '4.3' ? spine.state.getTrack(0) : spine.state.getCurrent(0)
if (track) {
const duration = object.animations.find((animation) => animation.name === object.selectedAnimation)?.duration || 0
const localTime = Math.max(0, frame / Math.max(1, fps) - object.timeOffset)
@@ -85,6 +87,7 @@ export class SpineRuntimeLayer {
const entry = this.entries.get(objectId)
const bone = entry?.spine.skeleton.findBone(boneName)
if (!entry || !bone || !bone.active) return null
const pose = entry.runtimeVersion === '4.3' ? bone.appliedPose : bone
// Spine 骨骼矩阵位于 Spine 对象局部空间;与外层 Pixi 容器矩阵组合后,
// 再把屏幕 Y 向下坐标转换为编辑器使用的数学坐标(Y 向上)。
@@ -95,12 +98,12 @@ export class SpineRuntimeLayer {
const rb = -sin * root.scale.y
const rc = sin * root.scale.x
const rd = cos * root.scale.y
const a = ra * bone.a + rb * bone.c
const b = ra * bone.b + rb * bone.d
const c = rc * bone.a + rd * bone.c
const d = rc * bone.b + rd * bone.d
const screenX = root.position.x + ra * bone.worldX + rb * bone.worldY
const screenY = root.position.y + rc * bone.worldX + rd * bone.worldY
const a = ra * pose.a + rb * pose.c
const b = ra * pose.b + rb * pose.d
const c = rc * pose.a + rd * pose.c
const d = rc * pose.b + rd * pose.d
const screenX = root.position.x + ra * pose.worldX + rb * pose.worldY
const screenY = root.position.y + rc * pose.worldX + rd * pose.worldY
return {
x: screenX,
y: -screenY,