Inquiring about Ysort issues in Godot 4"

Godot Version

v4.2.1.stable.official [b09f793f5]

Question

In the 2D game, each player has resources like weapons, clothing, and decorations, which need to be layered according to the player’s orientation. If multiple players are placed in one scene, how should the resource layers for each player be correctly planned? I currently know that Ysort is needed, but I don’t quite understand how to use it correctly. Now, when there are many resources in the scene, everything becomes disordered!

If I was making that I would y-sort only the player objects, not their contents, so they would inherit the y-sorting, making either everything be in front or eveything behind, for each player, no middle ground.

Originally, the player node contained three sub-resource nodes: weapons, clothing, and hair decorations. If I follow your method, then I need to find a way to merge them into a single sub-node!

Among them, the weapon node is more troublesome. It needs to be adjusted according to the player’s orientation to change the layering of the weapon node.

You could try using SubViewport, but im not sure how easy that is. The hard way is definitely effective, just override the drawing call on your player object and draw everything at once using RenderingServer instead of delegating to each node. More inconvenient and less scalable, but it would for sure work.

I found a good method, which involves creating several placeholder empty nodes within the player nodes. Set the order of the nodes properly, and then change the parent nodes of the weapon, headgear, etc., according to the player’s orientation, to the corresponding placeholder empty nodes.

@onready var player_weapon_index:Control = $Father/Body/WeaponIndex
@onready var player_wing_index:Control = $Father/Body/WingIndex

@rpc("any_peer", "call_local")
func on_switch_weapon_index() -> void:
	if player_weapon:
		if player_angle in [3, 4, 5]:
			player_weapon.reparent(player_weapon_index)
		else:
			player_weapon.reparent(player_body)
	if player_wing:
		if player_angle in [1, 2, 3]:
			player_wing.reparent(player_wing_index)
		else:
			player_wing.reparent(player_body)