Graphics Issue with updating Spine animations

C

Chrisss

Guest
I'm pretty new to Game Maker, and have been using Spine for my animations for my first project. Everything has generally been going well, but I have run into a big issue.

Whenever I add more images to my Spine animation project (eg. more types of armor to equip for my RPG) and then export the .json again to re-upload into Game Maker, the sprite comes in all jumbled up despite working before I added more images to my Spine animation.

I am assuming this is because adding images to the Spine project causes the exported .png that goes with the .json to be changed and re-arranged to include the new sprites.

Is there some way to fix this? I have made a bunch of animations for my character (all walking directions etc.) with the intention of adding more and more weapon/armor sprites to my Spine file as I make them and code in the items so they can be equipped into the various equipment slots in my Spine file. However it seems that I would need to have all the sprites I would ever use already in my source image folder before I start making my Spine project in order to not break anything, and then I couldn't add anything after if I needed to without remaking all my animations.

The odd thing here is that I have also added new images into some other Spine projects without having this issue, though it seems to happen more often than not.

I know there is a way to add sprites to Game Maker and run code to attach them to slots, but this is very unrealistic considering there will be about 6 slots of gear each with their own sprites, multiplied by at least 12 different animation sprites I would have to attach them to, times 20+ sets of equipment. Having all the items in the Spine file is much easier.

Hope someone can help!
 

rIKmAN

Member
I'm pretty new to Game Maker, and have been using Spine for my animations for my first project. Everything has generally been going well, but I have run into a big issue.

Whenever I add more images to my Spine animation project (eg. more types of armor to equip for my RPG) and then export the .json again to re-upload into Game Maker, the sprite comes in all jumbled up despite working before I added more images to my Spine animation.

I am assuming this is because adding images to the Spine project causes the exported .png that goes with the .json to be changed and re-arranged to include the new sprites.

Is there some way to fix this? I have made a bunch of animations for my character (all walking directions etc.) with the intention of adding more and more weapon/armor sprites to my Spine file as I make them and code in the items so they can be equipped into the various equipment slots in my Spine file. However it seems that I would need to have all the sprites I would ever use already in my source image folder before I start making my Spine project in order to not break anything, and then I couldn't add anything after if I needed to without remaking all my animations.

The odd thing here is that I have also added new images into some other Spine projects without having this issue, though it seems to happen more often than not.

I know there is a way to add sprites to Game Maker and run code to attach them to slots, but this is very unrealistic considering there will be about 6 slots of gear each with their own sprites, multiplied by at least 12 different animation sprites I would have to attach them to, times 20+ sets of equipment. Having all the items in the Spine file is much easier.

Hope someone can help!
What are your Spine Export Settings?
 
C

Chrisss

Guest
Update: I've found a workaround that works.

It seems I have to delete the sprite in Game Maker completely, and make a new one and import the .json again, and then it will work. It's annoying, as I'll have to do this for all of my sprites every time I want to add in some new armor sprites etc., but at least it means I can keep adding more sprites to my Spine file and not have to re-code anything as long as I name the new sprites the same thing as the deleted one. I'll probably end up only "updating" my sprites like this when I have a lot of new equipment sprited to add unless anyone knows a better way.
 

rIKmAN

Member
Update: I've found a workaround that works.

It seems I have to delete the sprite in Game Maker completely, and make a new one and import the .json again, and then it will work. It's annoying, as I'll have to do this for all of my sprites every time I want to add in some new armor sprites etc., but at least it means I can keep adding more sprites to my Spine file and not have to re-code anything as long as I name the new sprites the same thing as the deleted one. I'll probably end up only "updating" my sprites like this when I have a lot of new equipment sprited to add unless anyone knows a better way.
Ahh that old bug.

When you want to import your new json, select "Import Sprite" and choose the .png texture file.
Once that's loaded hit "Import Sprite" again and this time load the .json file and it'll import as normal.

For some reason GMS can't handle importing a json straight over a json.
It's been reported, but I'd advise you to get used to doing this as I doubt it'll be fixed anytime soon.

Import > Select the .png file > Import > Select the new .json file.
 
C

Chrisss

Guest
Ahh that old bug.

When you want to import your new json, select "Import Sprite" and choose the .png texture file.
Once that's loaded hit "Import Sprite" again and this time load the .json file and it'll import as normal.

For some reason GMS can't handle importing a json straight over a json.
It's been reported, but I'd advise you to get used to doing this as I doubt it'll be fixed anytime soon.

Import > Select the .png file > Import > Select the new .json file.
Oh, thanks for the tip! That will be much easier than deleting/remaking all my sprites.

Since you seem to know a lot about spine, maybe you could help me with another issue I am having so I don't have to make a new thread?

When I use the skeleton_attachment_set function in my code, it works when I use it as a step event, but it seems to be updating the sprite every frame and it also resets to the default attachment every frame. It looks like it is working normally as a step event that is always active, but it seems to be running the code over and over every frame. I noticed this because if I set it so that it switches the head attachment to a helmet when I press a key, it will only switch for one frame and then go back to the default head, and the same is true if the code is in the create event (flickers to the attachment for 1 frame and then to the default).
I am using sprite_index to set my sprites rather than setting the animations, if that matters.
 

rIKmAN

Member
Oh, thanks for the tip! That will be much easier than deleting/remaking all my sprites.

Since you seem to know a lot about spine, maybe you could help me with another issue I am having so I don't have to make a new thread?

When I use the skeleton_attachment_set function in my code, it works when I use it as a step event, but it seems to be updating the sprite every frame and it also resets to the default attachment every frame. It looks like it is working normally as a step event that is always active, but it seems to be running the code over and over every frame. I noticed this because if I set it so that it switches the head attachment to a helmet when I press a key, it will only switch for one frame and then go back to the default head, and the same is true if the code is in the create event (flickers to the attachment for 1 frame and then to the default).
I am using sprite_index to set my sprites rather than setting the animations, if that matters.
skeleton_attachment_set works fine in a create event, a button press event etc and will persist - it doesn't need to be set every frame.

Without seeing your code I would say that the issue is you using sprite_index rather than the skeleton functions, though I'm not sure what you are trying to do by trying to set an attachment using sprite_index.

Are you creating attachments at runtime?
 
C

Chrisss

Guest
skeleton_attachment_set works fine in a create event, a button press event etc and will persist - it doesn't need to be set every frame.

Without seeing your code I would say that the issue is you using sprite_index rather than the skeleton functions, though I'm not sure what you are trying to do by trying to set an attachment using sprite_index.

Are you creating attachments at runtime?
I have been using sprite_index because I have a bunch of different sprites that need to be used (ones that use completely different sprites/bones for 3 different character facings). I found that when I was using animation_set, it just wouldn't do anything (I had 3 sprites for the animations I needed, but calling to those animations wouldn't use them, only the animations in the sprite that I set to my player object). For example, if I had my player object set to have the down view of my sprite by default, it would play the walking down, idle down, or attack down animations I made, but if I tried to play something like my "walk up" animation, it wouldn't, presumably because that animation is for a different sprite. I switched to using sprite_index instead after that and saving all my animations as their own individual sprites to switch between, and that has been working for me until this issue came up.
I am not creating any attachments, just using ones that are already loaded in my .json files.
 

rIKmAN

Member
I have been using sprite_index because I have a bunch of different sprites that need to be used (ones that use completely different sprites/bones for 3 different character facings). I found that when I was using animation_set, it just wouldn't do anything (I had 3 sprites for the animations I needed, but calling to those animations wouldn't use them, only the animations in the sprite that I set to my player object). For example, if I had my player object set to have the down view of my sprite by default, it would play the walking down, idle down, or attack down animations I made, but if I tried to play something like my "walk up" animation, it wouldn't, presumably because that animation is for a different sprite. I switched to using sprite_index instead after that and saving all my animations as their own individual sprites to switch between, and that has been working for me until this issue came up.
I am not creating any attachments, just using ones that are already loaded in my .json files.
So you are using multiple Spine sprites, and a controller object to switch between the currently active sprite_index for different directions?
I've done it myself and works fine although I used multiple objects (one for each direction) and then used a controller to switch between / manage these as that suited my needs better.

It also sounds like you may be getting yourself confused between sprite_index (to change the skeleton sprite itself) and how to use attachments (images placed in slots inside Spine).

Are you sure each sprite (json) has the same animations for each direction?
If animations aren't playing or the character appears to be frozen still, then check your logic and that you aren't setting an animation every single frame as this will just keep setting it to frame 0 over and over resulting in no animation.

Are you sure the attachments and slots are named the same for each direction?
To change attachments on skeletons (any direction) you should be using skeleton_attachment_set() and passing the data you setup inside Spine for the slot/attachment.

I'd recommend starting a fresh project and just playing around with these functions until you get a handle on how they work.
Change attachments based on keypresses, changing the object / sprite based on keypresses etc, then once you start to get things working you ca go back to your main project and implement what you've learnt without getting too bogged down.
 
C

Chrisss

Guest
So you are using multiple Spine sprites, and a controller object to switch between the currently active sprite_index for different directions?
I've done it myself and works fine although I used multiple objects (one for each direction) and then used a controller to switch between / manage these as that suited my needs better.

It also sounds like you may be getting yourself confused between sprite_index (to change the skeleton sprite itself) and how to use attachments (images placed in slots inside Spine).

Are you sure each sprite (json) has the same animations for each direction?
If animations aren't playing or the character appears to be frozen still, then check your logic and that you aren't setting an animation every single frame as this will just keep setting it to frame 0 over and over resulting in no animation.

Are you sure the attachments and slots are named the same for each direction?
To change attachments on skeletons (any direction) you should be using skeleton_attachment_set() and passing the data you setup inside Spine for the slot/attachment.

I'd recommend starting a fresh project and just playing around with these functions until you get a handle on how they work.
Change attachments based on keypresses, changing the object / sprite based on keypresses etc, then once you start to get things working you ca go back to your main project and implement what you've learnt without getting too bogged down.
I am using multiple sprites, and I have code in my player object to switch the sprite_index.

I'm familiar with the difference between the sprite_index and attachments. I've been using sprite_index to switch the animations, but the attachment function to try to switch individual images in slots (helmet 1 to helmet 2, etc).

The .jsons all use the same animation names (walk is always walk no matter the facing, same with idle and attack, my only 3 animations currently). That second point might be the problem. All of my sprite_index code is in step events (user events mainly) and so when I switched it to animation_set instead of sprite_index it was causing my player to show a static sprite with no animation just as you said. The only issue is that I don't really know how to get around that problem, as the animation_set code needs to be in step events as far as I'm aware, since I am using state machines for my character and setting sprites/animations within them. My first thought would be setting an if statement to only play an animation if it isn't already playing so it doesn't reset it every frame, but I'm not sure if that is clunky or what function there is to check which animation is currently set.

I have worked in a fresh project before this to get used to spine, and followed a guide for setting animations via key press etc. but found some of those things weren't working the same in this project, probably due to what you noticed.
 

rIKmAN

Member
I am using multiple sprites, and I have code in my player object to switch the sprite_index.

I'm familiar with the difference between the sprite_index and attachments. I've been using sprite_index to switch the animations, but the attachment function to try to switch individual images in slots (helmet 1 to helmet 2, etc).

The .jsons all use the same animation names (walk is always walk no matter the facing, same with idle and attack, my only 3 animations currently). That second point might be the problem. All of my sprite_index code is in step events (user events mainly) and so when I switched it to animation_set instead of sprite_index it was causing my player to show a static sprite with no animation just as you said. The only issue is that I don't really know how to get around that problem, as the animation_set code needs to be in step events as far as I'm aware, since I am using state machines for my character and setting sprites/animations within them. My first thought would be setting an if statement to only play an animation if it isn't already playing so it doesn't reset it every frame, but I'm not sure if that is clunky or what function there is to check which animation is currently set.

I have worked in a fresh project before this to get used to spine, and followed a guide for setting animations via key press etc. but found some of those things weren't working the same in this project, probably due to what you noticed.
Just to clarify, when you are switching the sprite_index you aren't switching animations, you are switching the skeleton being used.
To switch animations you use skeleton_animation_set(), and to switch attachments you use skeleton_attachment_set().
It might have just been bad wording on you part, but just wanted to clarify.

I can't reply in full at the moment, but there may be an issue with changing the sprite_index between multiple skeletons on the same object and GM getting confused somehow, I'm not sure but weirder things have happened with GM and Spine.

You may need to re-set the animation and attachments each time you swap the sprite index for example, as nobody knows how GM is handling it internally and so possibly the previous settings you applied no longer apply to the new skeleton you are now using.

You could try making a quick test project and using 1 object per direction, and then a controller object to switch between these objects as the "currentSkeleton" or whatever, and test to see if that makes any different.

I've done this before and didn't have any problems - if indeed that is your issue.

For checking what animation is playing you can use skeleton_animation_get() - check the manual for the skeleton commands and have a read through them to get an idea of what you do. These checks don't need to be in a step event, but you must ensure they only fire conditionally and not every frame otherwise you get frame 0 constantly as the animation is set every frame.

If you are still stuck I can reply properly tomorrow, so test a few things out and give that test project a go and let me know how you get on.
I can maybe have a look at your project then and see what's going on.
 
C

Chrisss

Guest
Just to clarify, when you are switching the sprite_index you aren't switching animations, you are switching the skeleton being used.
To switch animations you use skeleton_animation_set(), and to switch attachments you use skeleton_attachment_set().
It might have just been bad wording on you part, but just wanted to clarify.

I can't reply in full at the moment, but there may be an issue with changing the sprite_index between multiple skeletons on the same object and GM getting confused somehow, I'm not sure but weirder things have happened with GM and Spine.

You may need to re-set the animation and attachments each time you swap the sprite index for example, as nobody knows how GM is handling it internally and so possibly the previous settings you applied no longer apply to the new skeleton you are now using.

You could try making a quick test project and using 1 object per direction, and then a controller object to switch between these objects as the "currentSkeleton" or whatever, and test to see if that makes any different.

I've done this before and didn't have any problems - if indeed that is your issue.

For checking what animation is playing you can use skeleton_animation_get() - check the manual for the skeleton commands and have a read through them to get an idea of what you do. These checks don't need to be in a step event, but you must ensure they only fire conditionally and not every frame otherwise you get frame 0 constantly as the animation is set every frame.

If you are still stuck I can reply properly tomorrow, so test a few things out and give that test project a go and let me know how you get on.
I can maybe have a look at your project then and see what's going on.
This has been very helpful, and I now have it working! It is far from optimal, and I'm sure there's a better way, but I have now wrapped all of my sprite_index code in if statements so the sprite is only changed if it is not already set to that sprite. I was having the same problem with my sprites being constantly set just like with the animation_set in a step event issue, except when using animations instead of sprites it would show my character frozen, while with sprites it looked like it was working because it wasn't visibly resetting the cycle every frame, even though it was setting my sprite over and over, causing the attachments to reset even though the animation was playing right.

For setting my attachments, I am now using a step event that sets the attachment only if that is not the attachment already set, which worked both as a key press and as a static effect. This also covers your point about re-setting the attachments when I switch skeletons, as it will always set them to the attachments I want if they are not for whatever reason.

Of course by the time this has been solved I've noticed another problem that I am having, but it is unrelated so I'll probably make a different thread for that. Such is learning!

Thanks for all your help so far, this has been invaluable to me.
 

rIKmAN

Member
This has been very helpful, and I now have it working! It is far from optimal, and I'm sure there's a better way, but I have now wrapped all of my sprite_index code in if statements so the sprite is only changed if it is not already set to that sprite. I was having the same problem with my sprites being constantly set just like with the animation_set in a step event issue, except when using animations instead of sprites it would show my character frozen, while with sprites it looked like it was working because it wasn't visibly resetting the cycle every frame, even though it was setting my sprite over and over, causing the attachments to reset even though the animation was playing right.

For setting my attachments, I am now using a step event that sets the attachment only if that is not the attachment already set, which worked both as a key press and as a static effect. This also covers your point about re-setting the attachments when I switch skeletons, as it will always set them to the attachments I want if they are not for whatever reason.

Of course by the time this has been solved I've noticed another problem that I am having, but it is unrelated so I'll probably make a different thread for that. Such is learning!

Thanks for all your help so far, this has been invaluable to me.
No worries, without seeing your code it's hard to give exact advice but I'm glad the general advice I could give helped you work it out! :)
 
C

Chrisss

Guest
No worries, without seeing your code it's hard to give exact advice but I'm glad the general advice I could give helped you work it out! :)
If you're curious and want to see the code, I have actually posted it in the thread for my other issue here.
 
Top