• 2D
  • How to solve the problem of sprite rendering order?

How to solve the problem of sprite rendering order? The sword and shield are separated into two sprites, and I need to change their display order in the animation. If I use z_index, the above problem will occur. Sword and shield are hidden behind trees. Since I need Ysort to sort according to the Y coordinate, and I want the sword and shield to only be rendered and sorted relative to the inside of the character, and for the outside they are integrated, how to solve this problem?

The character (KinematicBody2D3) has 3 sprites, two of which are sword and shield. The sword and shield are located behind the cha sprite at the beginning. I want to play the sword drawing animation, and the sword sprite is located in front of the cha sprite. This effect can be achieved with z_index. However, when the character is placed on the map and moved, due to the z_index rendering problem, the sword and shield are hidden behind the tree.

    a year later

    RequiemForAMeme Did you fix this? We have basically the same issue.

    quoting from the linked github issue comments:

    I solved this problem by calling the VisualServer.canvas_item_set_draw_index(sword.get_canvas_item(),index) function in the animation. Now I can call this function to change the rendering order of the sword at different keyframes, e.g. the sword is behind the character at the beginning and in front of the character after the sword is drawn. It would be nice if there was a property to set the rendering order in the animation. Currently, I need to implement it myself.

      Thanks for both of your replies. Sorry to both of you that I didn't really make my own situation clear and probably ended up wasting your time as a result. I'm making a cutout character with a 2D skeleton, and because of the hierarchy of the bones, the arm that is behind the character will be rendered above the back legs and it should be behind. If I use the Z_Index to send the arm back to render behind the legs, the arm will render behind other elements in the scene when using Y sort like in the gif in the op where the character's axe renders behind the mushroom.

      Megalomaniak I read that, but it didn't seem like the solution for me and I was very sleep deprived and didn't realize that that reply was from the OP and not someone else. Maybe it had something to do with the usernames in github and godot forums having different studio names. I was hoping that the OP had found a non-coding solution for this, like a setting in the top node of the character scene that would make all of its children render in the same Z index when placed in other scenes so that other characters or environment sprites wouldn't be sandwiched between the sprites in this character. I don't want to have to have code on every different type of character to move sprites back a few draw indexes.

      cybereality I don't think CanvasLayers will work for me. As far as I know, canvas layers won't work with Y-sorting. I suppose I could roll my own Y sort by changing each character's canvas layer's layer index, but I was really hoping that there was an out of the box solution for this. They also don't work with Z_indexs, so if I wanted to have some things in the environment below the characters and some above, they would also have to be on different layers. The other thing is, is having a ton of canvas layers performant? We're making a zombie game, so there could be upwards of 100 different canvas layers on the screen at once. I don't know that much about rendering in godot and I might be very wrong, but I feel like that would be a no-no.

      I think I have a working solution for now, which is to use RemoteTransform2Ds in the skeleton in place of the sprites, and then put all of the sprites outside of the skeleton where I can change their render order just by changing their order in the scene outliner. It's not ideal, but it seems to work so I'm going to go with this. Thanks again

        RequiemForAMeme I was hoping that the OP had found a non-coding solution for this,

        It may not be an entirely non-coding solution, but it does involve setting up a call-method track and triggering the method that holds the relevant script logic via the animation player.

        I don't need to change the render order at runtime, so then I would just have a function call in an animation to do something that should really be done in the scene hierarchy or inspector before the game is run. Not exactly ideal... Thanks anyway