jawny

Hello, I am having problems with the godot runtimes with skins. calling set_skin with a custom skin will randomly cause a crash with no output and no errors in the debugger

I set up a simple example, here is the Spine project:

https://i.imgur.com/1RDC80Y.gif

It's a simple skeleton with 3 skins controlled by a skin placeholder that each show a colored dot.

Here is the godot scene: a Node2D with 2 children, a SpineSprite and a Button to switch skins

https://i.imgur.com/LBeCWlz.gif

The script for reference: (switches between r and g skins, I used mix_and_match example as a template)
extends Node2D

onready var r_skin = $skeleton.get_skeleton().get_data().find_skin("r")
onready var g_skin = $skeleton.get_skeleton().get_data().find_skin("g")
var r_true=true

func _on_skinswitch_pressed():
var custom_skin = $skeleton.new_skin("customskin")
if r_true:
custom_skin.add_skin(g_skin)
r_true=false
else:
custom_skin.add_skin(r_skin)
r_true=true
$skeleton.get_skeleton().set_skin(custom_skin)
$skeleton.get_skeleton().set_slots_to_setup_pose()
When the code in this script is run, it can randomly cause the program to hang and crash with no output/errors

https://i.imgur.com/J7ju4H4.gif

I say random because it can happen after 1 swap, or after multiple swaps.
jawny
  • Posts: 8

Mario

Could you please send me a small Godot project that has all the assets and scripts in it so I can reproduce this? I can't reproduce it with our example project.
User avatar
Mario

Mario
  • Posts: 3283

jawny

Sure, I attached the godot project (blobgodot.zip) and the spine project (blobspine.zip).

I did try it on multiple machines and had the same issue.
You do not have the required permissions to view the files attached to this post.
jawny
  • Posts: 8

Mario

User avatar
Mario

Mario
  • Posts: 3283

jawny

--------------------

EDIT: this post is incorrect, this workaround did work but I'm not sure why. still looking into it, having custom_skin as a member variable seems to help

-----------------
I did manage to find a workaround, if you do all the find_skin methods as onready vars, then you can compose the new_skin with any of those variables with no crashing. The new_skin can have as many of the onready vars added to it as are required.
extends SpineSprite

var r_true=true
var custom_skin
var new_skin
onready var r_skin= get_skeleton().get_data().find_skin("r")
onready var g_skin= get_skeleton().get_data().find_skin("g")

func _on_skinswitch_pressed():
if !r_true:
custom_skin = new_skin("new")
custom_skin.add_skin(r_skin)
get_skeleton().set_skin(custom_skin)
get_skeleton().set_slots_to_setup_pose()
r_true=true
else:
custom_skin = new_skin("new")
custom_skin.add_skin(g_skin)
get_skeleton().set_skin(custom_skin)
get_skeleton().set_slots_to_setup_pose()
r_true=false
The problem comes into play when you try to find_skin and add_skin in the same frame, from what I can tell.

Luckily this workaround is pretty easy, although I guess it requires more memory since you have to load all the skins you want to use for a SpineSprite on creation rather than just when you'd need it. You could also set up the game loop to find_skin, wait a frame, then do new_skin if that's viable.
jawny
  • Posts: 8

Mario

There should never be a need for a workaround for basic functionality, especially not "magic" ones based on frame timing. I'm afraid I did not have time to look into this yet. My guess is _on_skinswitch_pressed() is executed before the SpineSprite is fully loaded, so $skeleton.get_skeleton() returns null. How that can happen I'm unsure yet. Will investigate next week.
User avatar
Mario

Mario
  • Posts: 3283

Mario

The issue linked to above has been closed in favor of this more complete issue: https://github.com/EsotericSoftware/spine-runtimes/issues/2185
User avatar
Mario

Mario
  • Posts: 3283

Mario

This is now fixed in the 4.1 and 4.2-beta branches.
User avatar
Mario

Mario
  • Posts: 3283


Return to Runtimes