• Runtimes
  • [Pixi8] How to dynamically change spine skeleton and atlas at runtime

Hi,
I’m currently working on a slot game where I’m using multiple spine animated symbols. Each slot symbol is a separate Spine object with its own skeleton and atlas. During the spin, I need to dynamically switch the skeleton and atlas of a Spine object to represent a different symbol.

I read about Skins and I think it might work but to achieve this via skins, I need to add all the symbols into one Spine project and dynamically change the skin right? Or is there a simpler way to dynamically reset the skeleton and atlas of a Spine object at runtime?

Any advice, best practices, or examples would be greatly appreciated. Thank you!

    Related Discussions
    ...

    Mirkobil

    Why dont you just switch out the spine object itself ?

    Obj A - has spine texture and atlas A
    Obj B - has spine texture and atlas B
    Keep both objects loaded in memory

    When you want to switch the symbol just swap out object A with B

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

      Mirkobil

      Having a single skeleton for all your symbols is not ideal, unless they don't reuse the same animations.
      The approach suggested by dylanjosh in the previous message is what you should probably do.

      dylanjosh due to memory constraints, I have 11 different Spine symbols and 25 tiles inside the reel. This setup requires creating 275 instances of Spine objects.. that's why I thought maybe I could keep only 11 instances in memory and assign them dynamically as needed.. is this possible?

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

        Spinebot I think this is for Unity... is there an alternative approach for pixi.js version 8?

        Mirkobil

        I've hidden Spinebot answer since it might be misleadings. The Spine object in Pixi is an optimized object that holds references to Spine internal items and cannot be reused with different assets.

        Once an object has been removed from the scene, it shouldn't be so heavy. Textures are shared across multiple instances of the same assets (below a Pixi texture there is a texture source that is the same istanc for the same loaded image asset).

        If you want to optimize this process, rather than using the factory Spine.from, you can use the constructor and create the Spine instance by yourself. If you do that, you have control over the SkeletonData being used.
        The SkeletonData is the in-memory representation of the data contained in you .skel or .json file.
        Multiple instances of a Spine object can reuse the same SkeletonData.

        If you don't want to keep the instance in memory, I'd instantiate a new symbol, or request it from a pool, as needed. Just be sure to load all its assets at the beginning. Then, when you don't need it anymore, you can destroy it, or release it in a pool for later reuse.

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

          Davide Thank you

          Yeah.. pooling might reduce memory usage by up to 5 times.. since basic idea here is reuse. However, I think the spine-pixi.js team should consider adding a built-in option to easily change the parameters of Spine instances. Similar to how you can change a sprite's texture "sprite.texture = newTexture", it would be great to have a method like
          this.spineObject.setData({ skeleton: "newSkel", atlas: "newAtlas" });
          to dynamically update the Spine instance.

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

            Mirkobil it would be great to have a method like
            this.spineObject.setData({ skeleton: "newSkel", atlas: "newAtlas" });
            to dynamically update the Spine instance.

            Doing as you suggested would be almost identical to destroy that instance a create a new one. The only benefits would be reuse the same Pixi container and write less code, that are interesting benefits, but don't change much about memory usage since a Pixi container is quite cheap to keep in memory.

            It's still an interesting use case that we'll consider since it might be useful to other users, and it's not so difficult to implement. Keep in mind though, that internally it will still be equivalent to destroy the old skeleton and create a new one.

            Yeah, sorry, I meant reassigning existing instances. In my case, I thought to keep instances of 11 symbols and, at the right time, assign them dynamically:
            this.spineObject.setData({ skeleton: otherSpine.skeleton, atlas: otherSpine.atlas });
            That would be great!

            Thank you anyway! I still want to reduce memory usage as much as possible, so I’ll try two methods.
            Create a single Spine project containing all symbols and animations or use a pooling pattern to manage instances.