diff --git a/spine-ts/spine-construct3/src/aces.json b/spine-ts/spine-construct3/src/aces.json index c4ebbeb3e..1bea2a28c 100644 --- a/spine-ts/spine-construct3/src/aces.json +++ b/spine-ts/spine-construct3/src/aces.json @@ -343,6 +343,42 @@ "type": "string" } ] + }, + { + "id": "bone-x", + "expressionName": "BoneX", + "highlight": false, + "returnType": "number", + "params": [ + { + "id": "bone-name", + "type": "string" + } + ] + }, + { + "id": "bone-y", + "expressionName": "BoneY", + "highlight": false, + "returnType": "number", + "params": [ + { + "id": "bone-name", + "type": "string" + } + ] + }, + { + "id": "bone-rotation", + "expressionName": "BoneRotation", + "highlight": false, + "returnType": "number", + "params": [ + { + "id": "bone-name", + "type": "string" + } + ] } ] } diff --git a/spine-ts/spine-construct3/src/c3runtime/expressions.ts b/spine-ts/spine-construct3/src/c3runtime/expressions.ts index 11e8c1ca5..5e99f70a7 100644 --- a/spine-ts/spine-construct3/src/c3runtime/expressions.ts +++ b/spine-ts/spine-construct3/src/c3runtime/expressions.ts @@ -8,12 +8,25 @@ C3.Plugins.EsotericSoftware_SpineConstruct3.Exps = Double (this: SDKInstanceClass, num: number) { return num * 2; }, + SlotAttachment (this: SDKInstanceClass, slotName: string) { if (!this.skeleton) return ""; const slot = this.skeleton.findSlot(slotName); if (!slot) return ""; const attachment = slot.pose.getAttachment(); return attachment ? attachment.name : ""; + }, + + BoneX (this: SDKInstanceClass, boneName: string) { + return this.getBoneX(boneName); + }, + + BoneY (this: SDKInstanceClass, boneName: string) { + return this.getBoneY(boneName); + }, + + BoneRotation (this: SDKInstanceClass, boneName: string) { + return this.getBoneRotation(boneName); } }; diff --git a/spine-ts/spine-construct3/src/c3runtime/instance.ts b/spine-ts/spine-construct3/src/c3runtime/instance.ts index fe9c77eca..14201a192 100644 --- a/spine-ts/spine-construct3/src/c3runtime/instance.ts +++ b/spine-ts/spine-construct3/src/c3runtime/instance.ts @@ -355,6 +355,77 @@ class SpineC3Instance extends globalThis.ISDKWorldInstanceBase { } } + public getBoneX (boneName: string): number { + const { skeleton } = this; + if (!skeleton) { + console.warn('[Spine] getBoneX: no skeleton'); + return 0; + } + + const bone = skeleton.findBone(boneName); + if (!bone) { + console.warn(`[Spine] getBoneX: bone not found: ${boneName}`); + return 0; + } + + const x = bone.applied.worldX; + const y = bone.applied.worldY; + const offsetX = this.x + this.propOffsetX; + const offsetAngle = this.angle + this.propOffsetAngle; + + if (offsetAngle) { + const cos = Math.cos(offsetAngle); + const sin = Math.sin(offsetAngle); + return x * cos - y * sin + offsetX; + } + return x + offsetX; + } + + public getBoneY (boneName: string): number { + const { skeleton } = this; + if (!skeleton) { + console.warn('[Spine] getBoneY: no skeleton'); + return 0; + } + + const bone = skeleton.findBone(boneName); + if (!bone) { + console.warn(`[Spine] getBoneY: bone not found: ${boneName}`); + return 0; + } + + const x = bone.applied.worldX; + const y = bone.applied.worldY; + const offsetY = this.y + this.propOffsetY; + const offsetAngle = this.angle + this.propOffsetAngle; + + if (offsetAngle) { + const cos = Math.cos(offsetAngle); + const sin = Math.sin(offsetAngle); + return x * sin + y * cos + offsetY; + } + return y + offsetY; + } + + public getBoneRotation (boneName: string): number { + const { skeleton } = this; + if (!skeleton) { + console.warn('[Spine] getBoneRotation: no skeleton'); + return 0; + } + + const bone = skeleton.findBone(boneName); + if (!bone) { + console.warn(`[Spine] getBoneRotation: bone not found: ${boneName}`); + return 0; + } + + const boneRotation = bone.applied.getWorldRotationX(); + const offsetAngle = this.angle + this.propOffsetAngle; + + return boneRotation + (offsetAngle * 180 / Math.PI); + } + private _setSkin () { const { skeleton } = this; if (!skeleton) return; diff --git a/spine-ts/spine-construct3/src/lang/en-US.json b/spine-ts/spine-construct3/src/lang/en-US.json index f7921921b..5a559bdfa 100644 --- a/spine-ts/spine-construct3/src/lang/en-US.json +++ b/spine-ts/spine-construct3/src/lang/en-US.json @@ -426,6 +426,36 @@ "desc": "Name of the slot" } } + }, + "bone-x": { + "description": "Get the world X position of a bone.", + "translated-name": "BoneX", + "params": { + "bone-name": { + "name": "Bone name", + "desc": "Name of the bone" + } + } + }, + "bone-y": { + "description": "Get the world Y position of a bone.", + "translated-name": "BoneY", + "params": { + "bone-name": { + "name": "Bone name", + "desc": "Name of the bone" + } + } + }, + "bone-rotation": { + "description": "Get the world rotation of a bone.", + "translated-name": "BoneRotation", + "params": { + "bone-name": { + "name": "Bone name", + "desc": "Name of the bone" + } + } } } } diff --git a/spine-ts/spine-construct3/src/lang/zh-CN.json b/spine-ts/spine-construct3/src/lang/zh-CN.json index c6f5f355a..e29533394 100644 --- a/spine-ts/spine-construct3/src/lang/zh-CN.json +++ b/spine-ts/spine-construct3/src/lang/zh-CN.json @@ -426,6 +426,36 @@ "desc": "插槽的名称" } } + }, + "bone-x": { + "description": "获取骨骼的世界X位置。", + "translated-name": "BoneX", + "params": { + "bone-name": { + "name": "骨骼名称", + "desc": "骨骼的名称" + } + } + }, + "bone-y": { + "description": "获取骨骼的世界Y位置。", + "translated-name": "BoneY", + "params": { + "bone-name": { + "name": "骨骼名称", + "desc": "骨骼的名称" + } + } + }, + "bone-rotation": { + "description": "获取骨骼的世界旋转角度。", + "translated-name": "BoneRotation", + "params": { + "bone-name": { + "name": "骨骼名称", + "desc": "骨骼的名称" + } + } } } }