# I want to flip my character on the horizontal axis, but what's the best way?

Attention Topic was automatically imported from the old Question2Answer platform.
Old Version Published before Godot 3 was released.

I’ve tried to use the `set_flip_h` in my script, but it says it’s nonexistent, so I guess I need to call the function somewhere, or create it? I’m also guessing in order to use that I need to grab the sprite node that’s a child of the Rigidbody2D?

I’ve also tried to just set the scale to -1 when going left, but it makes the character erratic and scale back and forth. Does anyone have a good way of flipping the character on the horizontal axis? Would creating a custom function to scale the character be the best way and then call it when I need it?

Any suggestions would rock from you guys. Thanks!

There may be a better way, but I currently have my script attached to my KinematicBody2D with the sprite as a child, and when left:

``````set_scale(Vector2(-1,1))
``````

when right:

``````set_scale(Vector2(1,1))
``````

This flips all of the children, including my CollisionShape2D that is slightly off center.

I tried this but my player acts funky when I try to move it. The code to move my character is this:

``````if rightButton:
set_axis_velocity(Vector2(moveSpeed, 0))
elif leftButton:
set_axis_velocity(Vector2(-moveSpeed, 0))
else:
set_axis_velocity(Vector2(0, 0))
``````

Should I use an & operator in this code or would I need to write the code differently to move my character and flip it?

Bleenx | 2016-05-13 14:44

Aside using set_scale, you can set the transform (which does exactly the same thing):

``````set_transform(Vector2(-1,0),Vector2(0,1),get_pos())
``````

In a recente project i created the function:

``````var Direction = "Left"

func ChangeDirection():
if Direction == "Left":
get_node( "Sprite" ).set_flip_h( false )
Direction = "Right"
elif Direction == "Right":
get_node( "Sprite" ).set_flip_h( true )
Direction = "Left"
``````

so, in any part of the program, call `ChangeDirection`, change the `sprite` of the object. You can improve this to have arguments and other parameters if you wish

This is my movement function:

``````func Movement():
var leftButton = Input.is_action_pressed("leftButton")
var rightButton = Input.is_action_pressed("rightButton")

if rightButton:
set_axis_velocity(Vector2(moveSpeed, 0))
elif leftButton:
set_axis_velocity(Vector2(-moveSpeed, 0))
else:
set_axis_velocity(Vector2(0, 0))
``````

Where would I call the ChangeDirection function? I can’t seem to get it to flip no matter what I do. Should I rewrite my movement code?

Bleenx | 2016-05-13 17:33

``````if rightButton:
get_node( "Sprite" ).set_flip_h( false ) #this line
...
``````

remember to change the path for the sprite and if the direction is wrong change false to true.

than tell me if works

tiernich | 2016-05-13 17:54

That worked! I was trying to add an “&” operator for some silly reason. My final movement code looked like this:

``````# Player Movement Control (left and right)---------------------|
func Movement():
var leftButton = Input.is_action_pressed("leftButton")
var rightButton = Input.is_action_pressed("rightButton")

if rightButton:
set_axis_velocity(Vector2(moveSpeed, 0))
get_node( "playerSprite" ).set_flip_h( false )
elif leftButton:
set_axis_velocity(Vector2(-moveSpeed, 0))
get_node( "playerSprite" ).set_flip_h( true)
else:
set_axis_velocity(Vector2(0, 0))
``````

Thanks a lot for your help. I had the right idea but was doing it completely wrong.

Bleenx | 2016-05-13 17:59

No problem

tiernich | 2016-05-13 18:03

I want to provide an answer for Godot 3 users who are stumbling upon this page in 2018, like I did:

You can accomplish flipping an entire Node2d and all its children through use of `apply_scale`.

Here is how I have horizontal flipping set up for my platform game:

``````const DIRECTION_RIGHT = 1
const DIRECTION_LEFT = -1
var direction = Vector2(DIRECTION_RIGHT, 1)

func set_direction(hor_direction):
if hor_direction == 0:
hor_direction = DIRECTION_RIGHT # default to right if param is 0
var hor_dir_mod = hor_direction / abs(hor_direction) # get unit direction
apply_scale(Vector2(hor_dir_mod * direction.x, 1)) # flip
direction = Vector2(hor_dir_mod, direction.y) # update direction
``````

Then, when needed, just call:

``````set_direction(DIRECTION_LEFT)
``````

or:

``````set_direction(DIRECTION_RIGHT)
``````

The Node2d will then flip if it is facing the opposite direction of the parameter.

The nice thing about this implementation is that the var `direction` can be applied to dependent scenes, such as when determining the direction of a projectile:

``````func create_projectile():
var projectile = PROJECTILE_SCENE.instance()
projectile.direction = direction
``````

Note the above function does not define `PROJECTILE_SCENE` or cover translating it to the correct coordinates - it is only to show the use of `direction`.

Finding this question years later when wondering the same thing myself, I found the following useful macros under part of Transform2D:

``````FLIP_X = Transform2D( -1, 0, 0, 1, 0, 0 )
Transform2D with mirroring applied parallel to the X axis.

FLIP_Y = Transform2D( 1, 0, 0, -1, 0, 0 )
Transform2D with mirroring applied parallel to the Y axis.
``````

These can be use to flip an object and all its children in a way similar to the one Rob describes in his answer, but in the following single line:

``````
transform *= Transform2D.FLIP_X
``````

and the funny thing about @Rob Blob is that the only code working is :

``````apply_scale(Vector2(-1, 1))
``````

and all the other stuff are excessive!

A disclaimer: be careful when trying to change your character’s rotation after modifying its transform. The rotation value is adjusted based on the transform at each processing step.

GreasyMcBeef | 2020-11-13 00:35

Sometimes simple is best, just stick to `set_flip_h()`, I’ve been using scale.x * -1 in order to reflect the sprite but this approach modifies de value of rotation_degrees and makes everything more complicated.

I found this out the hard way… My rotation was all screwy and had no idea why and after hours of debugging it hit me. Yes just use set_flip_h(). Less headache down the line.

fobmasta | 2021-10-09 21:17

This works for me:

``````if(_velocity.x > 0):
scale.x = scale.y * -1
elif(_velocity.x < 0):
scale.x = scale.y * 1
``````

Thank you very much!

Only this worked for me, and i have no idea why… if someone could explain, i will appreciate!!

gloostao | 2023-01-31 00:53

THIS WORKS!!! Thank you so much, i’m crying rn

JohnCoderunner3000 | 2023-03-16 03:42