It is indeed not possible without changes on the C++ side I'm afraid. The reason is that if you change a SkeletonDataResource
of a SpineSprite
, the underlying Skeleton
and AnimationState
instances need to be recreated.
The SpineSprite
simply can't know that all you did was merely change the texture atlas. Even "just" changing the atlas has a ton of side effects as Nate outlined. At a minimum, all the attachments of the skeleton (and its skins) need to reference the new atlas pages. That in itself is a problem, as you can create Skin
instances that contain deep copied attachments the runtime has no idea about, which would also need to reference the new atlas pages. The same is true for all sequences, which reference regions in atlas pages.
Even if all attachments could be rewired to use the new atlas pages (or rather, their textures), they'd then also would need to be update so their UV coordinates are recomputed (see RegionAttachment::updateRegion()
and MeshAttachment::updateRegion()
).
The only sensible option for SpineSprite
is thus to smoke the Skeleton
and AnimationState
instances and recreate them anew from the new SkeletonDataResource
you set.
With the current architecture, what you want to do is not possible, neither through GDScript nor the currently available C++ API. We'd have to significantly change the architecture to enable this use case cleanly, without breaking existing projects, which is not trivial.
One approach could work like this:
SpineSkeletonDataResource
doesn't reference just one but multiple atlases, e.g. in form of an array of SpineAtlasResource
instances. All atlases need to be compatible with the skeleton data!
SpineSprite
is aware of the multi-atlas nature of SpineSkeletonDataResource
and keeps an index into the atlas array which represents the active atlas. The index can be changed by a setter. If the index changes, then the sprite will:
- Iterate through all the attachments and update their regions as discussed above, including calls to
updateRegion()
- Iterate through all sequences and update their regions as well.
There're some caveats of course. The point of SpineSkeleotnDataResource
is to be able to share as much data between SpineSprite
instances as possible. That includes attachments and atlas regions. What I've outlined above would modify the attachments, rewiring them to point to regions of a different atlas. This would affect all SpineSprite
instances that reference the same SpineSkeletonDataResource
. This might possibly work for your game, but may not work for other projects.
So, while it's sort of possible to do what you want, I can not provide a good, general solution for everyone. As such, I can't commit to implementing this in the runtime at the moment. You could give it a try yourself by modifying the existing sources as outlined above.
The alternative is to better understand your use case. What problem are you actually trying to solve? To me, this sounds like the perfect use case for mip maps. What you are doing sounds like you're implementing mip map generation and mip level selection manually.