• Runtimes
  • Runtime scaling of skeleton fails when using PathConstraints

Hello,
I‘m using the libgdx runtime library to render Spine skeletons. This works without problems.
Now I wanted to change the scale of the skeleton at runtime. I did this by applying a scale to the root bone of the skeleton.
This works for most of the bones. However a few bones have a path constraint and those bones get not scaled correctly. The path constraint is set to chain scale and percent position and spacing.
In my case I have a path constraint on the legs of my character and when I scale it the legs are drawn way too large in comparison to all other bones.

I‘m not sure if I‘m doing something wrong or if this is a bug of the Spine runtime.

When I set the scale when json loading it works correctly but I want to be able to change the scale dynamically.

I hope you can help me.
Thanks

Related Discussions
...

Do you see the same behavior when you scale the root bone in the Spine editor? Have you disabled inherit scale? Can you post or email your project so we can see what is happening? contact@esotericsoftware.com FWIW, the stretchyman example is using a similar setup and scaling the root bone in the editor works as expected.

In the Spine editor everything works as expected. I can scale the root bone and it scales the whole skeleton without issues.
I haven't disabled inherit scale.
It happens only when scaling the root bone at runtime.

I just tried the stretchyman example and I can reproduce the issue.
Just try the following minimum sample and you should also see the issue. I used the files from here: Stretchyman example

public class SpineTest implements ApplicationListener {
    private Skeleton skeleton;
    private AnimationState animationState;
    private SkeletonRenderer renderer;

private PolygonSpriteBatch batch;

@Override
public void create() {
    TextureAtlas atlas = new TextureAtlas(Gdx.files.internal("stretchyman.atlas"));

    SkeletonJson json = new SkeletonJson(atlas);
    SkeletonData data = json.readSkeletonData(Gdx.files.internal("stretchyman-pro.json"));

    skeleton = new Skeleton(data);

    AnimationStateData stateData = new AnimationStateData(data);
    stateData.setDefaultMix(0.2f);

    animationState = new AnimationState(stateData);

    renderer = new SkeletonRenderer();

    batch = new PolygonSpriteBatch();
}

@Override
public void resize(int width, int height) {}

@Override
public void render() {
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    Gdx.gl.glClearColor(0, 0, 0, 1);

    float delta = Gdx.graphics.getDeltaTime();

    animationState.update(delta);
    animationState.apply(skeleton);
    skeleton.setPosition(250, 250);

    skeleton.getRootBone().setScale(0.5f);

    skeleton.updateWorldTransform();

    batch.begin();
    renderer.draw(batch, skeleton);
    batch.end();
}

@Override
public void pause() {}

@Override
public void resume() {}

@Override
public void dispose() {}
}

I would expect that the whole skeleton will be drawn at half its size but as you can see yourself it's totally off.


As a workaround to the issue, is it maybe possible to scale the viewport camera or the batch before drawing the skeleton and directly afterwards reset it again?

Stretchyman differs in that the arms, feet, and head (and right hand and left toe, for some reason) bones disable inheriting scale. Are you 100% sure you haven't disabled scale inheritance? If I inherit scale on all stretchyman bones, export, load with spine-libgdx, and change the root scale, it works as expected.

Other ways to scale are to set Skeleton scaleX and/or Skeleton scaleY, which will scale the whole skeleton even if scale inheritance is disabled. You can also modify the batch matrices, as you mentioned, but the root bone or skeleton scale is likely easier.

Thanks a lot, problem solved. Through your link to Skeleton scaleX, scaleY I found out that I still had an old version of Spine runtime which used flipX and flipY instead. Not sure why I thought I already used the latest version. Now everything works as expected.

Great, glad you got it figured out! 🙂