• Runtimes
  • SpineGameObject Not Centered in Bounding Box in Phaser 3 - Possible Bug?

Hi Spine Community

I’m using the spine-phaser plugin in a Phaser 3 project to display Spine animations (SpineGameObject). I’ve noticed that the character (spineboy) is not centered within its Bounding Box, even though I’ve set the pivot to { x: 0.5, y: 0.5 }. I suspect this might be a bug with how the Bounding Box is calculated or interpreted by spine-phaser.

The Issue
I’m positioning spineboy at specific points on the screen using an anchor-based system. I calculate the position (finalX, finalY), adjust it for the pivot, and set the origin with setOrigin(pivot.x, pivot.y). However:

The green rectangle (Bounding Box, based on skeleton.data.width/height) shows the character offset downward.
The red dot (origin, set to pivot: { x: 0.5, y: 0.5 }) is not at the visual center of the character; it’s also offset downward.
My Setup:
Phaser Version: 3.88.2
spine-phaser Version: 4.2.74
Spine Editor Version: 4.2 (assumed based on @esotericsoftware/spine-core version 4.2.70)
Spine Asset: Using spineboy-pro.skel (the example asset).
Code Snippet
Here’s how I position the character:

`if (sprite instanceof SpineGameObject) {
const scaleX = sprite.scaleX;
const scaleY = sprite.scaleY;

const spriteWidth = (sprite.skeleton?.data?.width 100) * scaleX;
const spriteHeight = (sprite.skeleton?.data?.height
100) * scaleY;

const pivot = { x: 0.5, y: 0.5 };
sprite.setOrigin(pivot.x, pivot.y);
sprite.setPosition(
finalX - spriteWidth * (pivot.x - 0.5),
finalY - spriteHeight * (pivot.y - 0.5)
);
sprite.setScale(scaleX, scaleY);
sprite.setVisible(true);

this.debugPivotAndAnchor(sprite, "spineboy", finalX, finalY);
}`

And my debug function:
`private debugPivotAndAnchor(
sprite: Phaser.GameObjects.Sprite | SpineGameObject,
elementName: string,
finalX: number,
finalY: number
): void {
const graphics = this.scene.add.graphics();


const scaleX = sprite.scaleX;
const scaleY = sprite.scaleY;
const width = (sprite.skeleton?.data?.width 100) * scaleX;
const height = (sprite.skeleton?.data?.height
100) * scaleY;


const originX = sprite.x;
const originY = sprite.y;


// Red dot at origin (pivot)
graphics.fillStyle(0xff0000, 1);
graphics.fillCircle(originX, originY, 10);


// Yellow dot at anchor position
graphics.fillStyle(0xffff00, 1);
graphics.fillCircle(finalX, finalY, 10);


// Green rectangle for bounding box
graphics.lineStyle(2, 0x00ff00, 1);
graphics.strokeRect(
sprite.x - width * sprite.originX,
sprite.y - height * sprite.originY,
width,
height
);


this.scene.time.delayedCall(15000, () => {
graphics.destroy();
});
}`

Screenshot Description:
I’ve attached a screenshot showing spineboy positioned at 9 anchor points on the screen. Each instance has:

A green rectangle (Bounding Box from skeleton.data.width/height).
A red dot (origin, set to pivot: { x: 0.5, y: 0.5 }).
You’ll see that spineboy is offset upward within the green rectangle, and the red dot is not at his visual center.
Questions:

  1. Is this a known issue with spine-phaser 4.2.74 or Spine’s Bounding Box calculation?
    2 How can I ensure the Bounding Box aligns with the visual center of the character in Phaser?
  2. Are there specific export settings in Spine Editor I should use to fix this?

Thanks for any help!

Related Discussions
...

It seems like you're experiencing an issue with the alignment of the SpineGameObject's bounding box in Phaser 3. This could be related to how the bounding box is calculated or interpreted by the spine-phaser plugin. Here are some insights and suggestions:

  1. Bounding Box Calculation: The bounding box in Spine is typically based on the skeleton's setup pose. If the character appears offset, it might be due to the setup pose not being centered around the origin. You can check the setup pose in the Spine Editor to ensure that the character is centered.

  2. Phaser and Spine Integration: The spine-phaser plugin might have specific ways of handling bounding boxes and origins. Ensure that the plugin version you are using is compatible with your Phaser version. Sometimes, updates or patches might address such issues.

  3. Export Settings in Spine Editor: When exporting from Spine, ensure that the export settings are correctly configured. The bounding box should be aligned with the character's visual center. You might need to adjust the setup pose or the export settings to ensure proper alignment.

  4. Debugging and Adjustments: Your debug function is a good start. You might want to manually adjust the position of the bounding box or the origin in your code to see if it resolves the issue. This can help identify if the problem is with the bounding box calculation or the integration with Phaser.

  5. Known Issues: There are no specific known issues with spine-phaser 4.2.74 regarding bounding box alignment, but it's always a good idea to check the latest updates or community discussions for any reported bugs.

By ensuring that the setup pose in Spine is correctly centered and verifying the export settings, you should be able to achieve better alignment of the bounding box with the visual center of the character in Phaser.

  • momi님이 이에 답장했습니다.

    Spinebot

    Thank you for the response!

    I’ve tried your suggestions, but the issue persists. I checked the Setup Pose in Spine Editor and ensured the origin (0,0) is at the visual center of spineboy. I also created a new Bounding Box (spineboy_bbox) that fits the character’s visual size and re-exported the .skel file. However, in Phaser, the character is still offset downward within the Bounding Box, and the origin (red dot) is not at the visual center.

    I’ve also verified compatibility between Phaser 3.88.2 and spine-phaser 4.2.74, and they seem to be compatible. I tried manually adjusting the position in code, but it didn’t resolve the underlying issue.

    Could this be an issue with the spine-phaser plugin itself? Is there a way to inspect the Bounding Box calculation directly through the plugin, or are there additional settings I might be missing?

    Thanks for the help!

    • Davide님이 이에 답장했습니다.

      momi

      The skeleton is always drawn with its root bone centered on the game object's position.
      The bounds of a Phaser game object depend on its width and height and are centered on the origin.
      Moving the origin only affects the bounds—the skeleton will still be drawn centered on the game object's position.

      momi

      After some thought, I realized that the current behavior makes it impossible to properly sync the position of the drawn skeleton with the Phaser game object.

      The skeleton should be drawn relative to the origin, so that moving the origin affects both the drawn skeleton and the bounds.

      Right now, moving the origin only shifts the bounds, while the skeleton remains anchored to the game object's position.

      I'll implement a fix tomorrow. I just need to figure out how to make it non-breaking. Most likely, the default behavior will be to set the origin at the root bone position.

      I've made the fix in 4.2.78.
      You can have a look at this example that shows Spine gameobject works exactly like normal Phaser gameobjects.

      Hi Davide,

      Thank you so much for your help and kindness! I'll try applying the fix to my code and keep you updated.

      Best,
      Momi

      • Davide님이 이에 답장했습니다.

        momi

        While I was solving another phaser issue I've noticed that when a game object is rotated, the bounds was again misaligned. Please, use version 4.2.79 that should handle that 🙂
        I've updated the example too.