Add setBounds action and related bounds expressions to modify skeleton bounds at runtime.

This commit is contained in:
Davide Tantillo 2026-03-04 12:35:54 +01:00
parent 728186bb4f
commit 2d3e56c735
6 changed files with 181 additions and 0 deletions

View File

@ -615,6 +615,33 @@
"type": "string"
}
]
},
{
"id": "set-bounds",
"scriptName": "SetBounds",
"highlight": false,
"params": [
{
"id": "x",
"type": "number",
"initial-value": 0
},
{
"id": "y",
"type": "number",
"initial-value": 0
},
{
"id": "width",
"type": "number",
"initial-value": 200
},
{
"id": "height",
"type": "number",
"initial-value": 200
}
]
}
],
"expressions": [
@ -761,6 +788,30 @@
"type": "number"
}
]
},
{
"id": "bounds-x",
"expressionName": "BoundsX",
"highlight": false,
"returnType": "number"
},
{
"id": "bounds-y",
"expressionName": "BoundsY",
"highlight": false,
"returnType": "number"
},
{
"id": "bounds-width",
"expressionName": "BoundsWidth",
"highlight": false,
"returnType": "number"
},
{
"id": "bounds-height",
"expressionName": "BoundsHeight",
"highlight": false,
"returnType": "number"
}
]
}

View File

@ -178,6 +178,10 @@ C3.Plugins.EsotericSoftware_SpineConstruct3.Acts =
RemoveHandle (this: SDKInstanceClass, type: 0 | 1, name: string) {
this.removeDragHandle(type, name);
},
SetBounds (this: SDKInstanceClass, x: number, y: number, width: number, height: number) {
this.setBounds(x, y, width, height);
}
};

View File

@ -98,5 +98,21 @@ C3.Plugins.EsotericSoftware_SpineConstruct3.Exps =
CurrentAnimationLast (this: SpineC3Instance, trackIndex: number) {
const track = this.state?.tracks[trackIndex];
return track?.animationLast ?? 0;
},
BoundsX (this: SpineC3Instance) {
return this.getBounds().x;
},
BoundsY (this: SpineC3Instance) {
return this.getBounds().y;
},
BoundsWidth (this: SpineC3Instance) {
return this.getBounds().width;
},
BoundsHeight (this: SpineC3Instance) {
return this.getBounds().height;
}
};

View File

@ -515,6 +515,7 @@ class SpineC3Instance extends globalThis.ISDKWorldInstanceBase {
this.collisionSpriteInstance.width = this.width;
this.collisionSpriteInstance.height = this.height;
this.collisionSpriteInstance.angleDegrees = this.angleDegrees;
this.collisionSpriteInstance.setOrigin(this.originX, this.originY);
}
private calculateBounds () {
@ -1151,6 +1152,37 @@ class SpineC3Instance extends globalThis.ISDKWorldInstanceBase {
/**********/
/*
* Bounds
*/
public setBounds (x: number, y: number, width: number, height: number) {
if (width <= 0 || height <= 0) {
console.warn('[Spine] setBounds: width and height must be positive');
return;
}
const scaleX = (Math.abs(this.width) / this.spineBounds.width) * this.propScaleX;
const scaleY = (Math.abs(this.height) / this.spineBounds.height) * this.propScaleY;
this.spineBounds = { x, y, width, height };
this.setOrigin(-x / width, y / height);
this.width = width * scaleX * (this.isMirrored ? -1 : 1);
this.height = height * scaleY * (this.isFlipped ? -1 : 1);
this.propScaleX = 1;
this.propScaleY = 1;
this.updateCollisionSprite();
}
public getBounds () {
return { ...this.spineBounds };
}
/**********/
};
C3.Plugins.EsotericSoftware_SpineConstruct3.Instance = SpineC3Instance;

View File

@ -721,6 +721,29 @@
"desc": "Name of the bone or slot to remove handle from"
}
}
},
"set-bounds": {
"list-name": "Set bounds",
"display-text": "Set bounds to ({0}, {1}, {2}, {3})",
"description": "Set the bounds of the game object in Spine world coordinates. The skeleton's visual size stays the same (only the bounding area changes). The skeleton remains rendered at the same position.",
"params": {
"x": {
"name": "X",
"desc": "X offset of the bounds in Spine world coordinates"
},
"y": {
"name": "Y",
"desc": "Y offset of the bounds in Spine world coordinates"
},
"width": {
"name": "Width",
"desc": "Width of the bounds in Spine world coordinates"
},
"height": {
"name": "Height",
"desc": "Height of the bounds in Spine world coordinates"
}
}
}
},
"expressions": {
@ -841,6 +864,22 @@
"desc": "The track index"
}
}
},
"bounds-x": {
"description": "Get the X offset of the current bounds.",
"translated-name": "BoundsX"
},
"bounds-y": {
"description": "Get the Y offset of the current bounds.",
"translated-name": "BoundsY"
},
"bounds-width": {
"description": "Get the width of the current bounds.",
"translated-name": "BoundsWidth"
},
"bounds-height": {
"description": "Get the height of the current bounds.",
"translated-name": "BoundsHeight"
}
},
"custom_ui": {

View File

@ -721,6 +721,29 @@
"desc": "要移除控制柄的骨骼或插槽名称"
}
}
},
"set-bounds": {
"list-name": "设置边界",
"display-text": "设置边界为({0}, {1}, {2}, {3})",
"description": "在Spine世界坐标中设置游戏对象的边界。骨架的视觉大小保持不变只有边界区域改变。骨架保持在相同位置渲染。",
"params": {
"x": {
"name": "X",
"desc": "边界在Spine世界坐标中的X偏移"
},
"y": {
"name": "Y",
"desc": "边界在Spine世界坐标中的Y偏移"
},
"width": {
"name": "宽度",
"desc": "边界在Spine世界坐标中的宽度"
},
"height": {
"name": "高度",
"desc": "边界在Spine世界坐标中的高度"
}
}
}
},
"expressions": {
@ -841,6 +864,22 @@
"desc": "轨道索引"
}
}
},
"bounds-x": {
"description": "获取当前边界的X偏移。",
"translated-name": "BoundsX"
},
"bounds-y": {
"description": "获取当前边界的Y偏移。",
"translated-name": "BoundsY"
},
"bounds-width": {
"description": "获取当前边界的宽度。",
"translated-name": "BoundsWidth"
},
"bounds-height": {
"description": "获取当前边界的高度。",
"translated-name": "BoundsHeight"
}
},
"custom_ui": {