• Runtimes
  • Help with Aligning PixiJS Objects to Spine Slots in spine-pixi-v8

'm working on a game using spine-pixi-v8 and need to dynamically attach weapons (PixiJS sprites) to a hand slot in my Spine skeleton. Each weapon has different sizes and pivot points for attachment (e.g., hilt for swords, handle for axes), but I'm struggling to align them correctly with the bone.

Here's my current code:

const texture = await loadAssetTexture(asset);
const bone = this.avatar.spine.skeleton.findBone(slot);
const sprite = new Sprite(texture);
if (bone) {
    sprite.rotation = bone.rotation;
    sprite.position.copyFrom(bone);
}
this.avatar.spine.addSlotObject(slot, sprite);

The alignment is off, and I think it's because I'm setting transformations manually. I've tried setting pivots, but weapons don't align properly with the hand. How can I ensure each weapon aligns correctly, accounting for different sizes and pivot points? Any advice would be appreciated!

Also my textures might not all be the same size. Is there any way to do this?

  • Davide ответили на это сообщение.
    Related Discussions
    ...

    To align PixiJS objects to Spine slots correctly, especially when dealing with different sizes and pivot points, you need to ensure that the pivot of each weapon sprite is set correctly relative to the attachment point on the Spine skeleton. Here are some steps and tips to help you achieve this:

    1. Set the Pivot Point: For each weapon sprite, set the pivot point to the location where it should attach to the hand. This is typically done by setting the sprite.pivot property. For example, if the pivot should be at the hilt of a sword, adjust the pivot coordinates accordingly.

    2. Use Bone Transformations: Instead of manually setting the rotation and position, you can use the bone's world transformation to ensure the sprite aligns correctly. This involves using the bone's world position and rotation to transform the sprite.

    3. Adjust for Different Sizes: If your textures are of different sizes, you may need to scale the sprite to match the expected size in the game world. This can be done by setting the sprite.scale property.

    4. Dynamic Adjustment: You can create a function that dynamically adjusts the pivot and scale based on the weapon type. This function can take parameters for the weapon type and adjust the sprite properties accordingly.

    Here's an example of how you might adjust your code:

    const texture = await loadAssetTexture(asset);
    const bone = this.avatar.spine.skeleton.findBone(slot);
    const sprite = new Sprite(texture);
    
    if (bone) {
        // Set the pivot point based on weapon type
        sprite.pivot.set(desiredPivotX, desiredPivotY); // Adjust these values based on the weapon
    
        // Use bone's world transformation
        sprite.position.set(bone.worldX, bone.worldY);
        sprite.rotation = bone.worldRotation * (Math.PI / 180); // Convert to radians if necessary
    
        // Adjust scale if needed
        sprite.scale.set(desiredScaleX, desiredScaleY); // Adjust these values based on the weapon
    }
    
    this.avatar.spine.addSlotObject(slot, sprite);

    By setting the pivot and using the bone's world transformation, you should be able to align the weapons correctly with the hand slot. Adjust the desiredPivotX, desiredPivotY, desiredScaleX, and desiredScaleY based on the specific weapon's requirements.

    benjaminhon

    Hello,

    As explained in the documentation:

    to ensure more control over the added objects, it is highly recommended to wrap the object you want to add into a Pixi Container. This allows you to add multiple Pixi objects, adjust their position, angle, scale, and more, without being restricted by Spine's automatic modifications.

    Create a container for your weapons add that as slot object. Then add your sprites with the changed pivot to the container. Here an example:

    // create weapon sprite and set the pivot
    const weapon = PIXI.Sprite.from('weapon');
    weapon.pivot.set(50, 50)
    
    // create the weapons container and add one of the weapons to it
    const weaponsContainer = new PIXI.Container();
    weaponsContainer.addChild(weapon);
    
    // add the weapons container as a slot object to the desired bone
    character.addSlotObject("gun", weaponsContainer);

    Hi @Davide

    const sprite = new Sprite(texture);
    
    const container = new Container();
    
    container.addChild(sprite);
    
    sprite.angle = bone.localToWorldRotation(
        bone.rotation
    );
    
    this.avatar.spine.addSlotObject(slot, container);

    this works, however for some animations the weapon flips 180 degrees, even though it is correct in spine not sure if you have experience this before?

    • Davide ответили на это сообщение.

      Hmm instead i think maybe its easier to add 1 basic weapon for each weapon type as a skin. Then in runtime swap the texture of the skin so that all the rotations kept.

      however how does one swap the texture with an external texture (not in the atlas)? i saw there was some hacks for the pixi v7 runtime but didnt see one for the v8 runtime.

      • Davide ответили на это сообщение.

        benjaminhon

        this works, however for some animations the weapon flips 180 degrees, even though it is correct in spine not sure if you have experience this before?

        The weapon should automatically rotate with the bone since the container's rotation is bound to the bone's rotation. If you want to add an initial rotation, be mindful when using bone.rotation because its value changes with skeleton updates.

        However, I cannot get a 180 degree flip as you described. Could you share a repro of that?

        benjaminhon Hmm instead i think maybe its easier to add 1 basic weapon for each weapon type as a skin. Then in runtime swap the texture of the skin so that all the rotations kept.

        however how does one swap the texture with an external texture (not in the atlas)? i saw there was some hacks for the pixi v7 runtime but didnt see one for the v8 runtime.

        addSlotObject was added to allow custom textures and to avoid using the hack function you mentioned. So, let's try to make it work with addSlotObject.