+3 votes

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!

asked May 13, 2016 in Engine by Bleenx (31 points)
edited May 13, 2016 by Bojidar Marinov

4 Answers

+3 votes
Best answer

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

answered May 13, 2016 by tiernich (423 points)
selected May 13, 2016 by Bleenx

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?

ok, add the line:

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

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. :)

No problem :D

+6 votes

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.

answered May 13, 2016 by nokungfu (30 points)

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?

0 votes

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())
answered May 13, 2016 by Gokudomatic2 (689 points)
+7 votes

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
    get_parent().add_child(projectile)

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.

answered Jun 3, 2018 by Rob Blob (28 points)
edited Jun 4, 2018 by Rob Blob
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.