Best way to flip a character and all of its collisions, areas 2D

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Nikola-Milovic

What is the best way to manage flipping a character from left to right and so on? For example, you have a character with a collision shape, sprite, and area2d with collision shape to detect sword swings. How would you approach flipping this character to the left side and back to the right? I find that doing each separate node and flipping it with

node.position.x = direction * HARDCODED DISTANCE 

The hardcoded distance part is what disturbs me, when I have a area2D that is positioned like 2 on the x and 0 on y, to flip it I have to hard code direction * 2 to always keep it the same distance. How do you handle flipping nodes and flipping all of the hit boxes areas and everything to flip with it? Anyway to avoid hardcoding values?
2D, 2 directions, left and right

:bust_in_silhouette: Reply From: njamster

You can invert the scale-property of the root-node in your character-scene. Instead of using Vector2(1, 1) you can use Vector2(-1, 1) to flip it horizontally or Vector2(1, -1) to flip it vertically. Of course doing both at once is also possible.

Thank you but I wouldnt have posted a question if I hadn’t tried everything. This doesnt work. It flips the character on the x and y axis randomly.
Imgur: The magic of the Internet

I also tried just the scale.x, position, I tried 20 fixes and ideas from guys over at discord and nothing, absolutely nothing has worked.

Nikola-Milovic | 2020-03-23 15:14

This does work! However, not for physics bodies, see this issue.

That same issue mentions a “fix” for your problem in the end:

scale.x = scale.y * direction

However, I don’t fully understand why this works, so I’d recommend sticking with Zylann’s advice of only adjusting the scale for visual nodes (e.g. a Sprite) instead. So something like this should work and not required any HARDCODED DISTANCE:

func change_dir(dir):
if look_at != direction:
	$CollisionShape2D.position.x *= -1
	look_at = direction
	$Sprite.scale.y = direction

njamster | 2020-03-23 16:39

Yeyyy, finally. I would’ve never guessed that this works the way it does… Thanks a lot. It’s properly working now.

Nikola-Milovic | 2020-03-23 18:06

You are a genius
Thank you!

Natink26 | 2020-09-15 12:45

omg that is so usefull thank you so much

Sniper | 2021-08-21 20:51