Godot Version
4.6
Question
Hi, I have a CharacterBody2D with a fully rigged 2D character using Skeleton2D, FABRIK and CCDIK for arms/legs, and a LookAtModifier2D for the head.
I want my character to flip left/right based on movement.
Current issues:
-
Using scale.x = -1 on the root flips the head vertically (LookAt breaks).
-
The feet IK doesn’t mirror correctly.
-
Animations become unstable when mirroring the skeleton.
What’s the best practice way to flip a 2D character with IK and LookAt?
-
Should I flip the root node, Skeleton2D, or just adjust IK targets?
-
Should the head/feet targets be flipped separately?
-
Are there recommended node hierarchies or scripts for stable flipping?
I’d appreciate any examples in GDScript or explanations of why certain flipping approaches break IK/LookAt.
Thanks!
Is the head rotated by default? that could be the issue.
Yes, usually calling self.scale.x = -1 on the entire node works and is fine, in this case though its kinda hard to say why it isnt working other than the above hypothesis.
Use SoupIK Instead. Flipping the head separately is up to you.
This is what mine looks like. You flip everything.
Here’s the code on the Facing node.
extends Node2D
@onready var player: Player = get_parent()
@onready var player_movement_state_machine: StateMachine = %"Player Movement State Machine"
@onready var collision_shape_2d: CollisionShape2D = $"../CollisionShape2D"
@onready var character_skin: CharacterSkin = %CharacterSkin
func _physics_process(_delta: float) -> void:
var new_horizontal_facing: float = scale.x
if player.direction < 0:
new_horizontal_facing = -1.0
elif player.direction > 0:
new_horizontal_facing = 1.0
if player_movement_state_machine._current_state is WallSlidePlayerState:
new_horizontal_facing *= -1.0
if new_horizontal_facing != scale.x:
scale.x = new_horizontal_facing
character_skin.flip_horizontal = new_horizontal_facing < 0
var new_vertical_facing: float = scale.y
if player.get_gravity().y <= 0:
new_vertical_facing = -1.0
elif player.get_gravity().y > 0:
new_vertical_facing = 1.0
if new_vertical_facing != scale.y:
scale.y = new_vertical_facing
character_skin.flip_vertical = new_vertical_facing < 0