Scale X not assigning but multiplying

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

So I was trying to make a patrolling AI and was using a RayCast2D to check if there is floor ahead but ran into an issue where if try to assign scale.x to one or negative one it would multiply it rather than set it equal to the value. I don’t know if this is a glitch that is only on my machine because I got this working on my Surface perfectly fine.

Please post the line of code which you use to scale.

mfabjan | 2018-10-24 12:19

if right == true:
    $RayCast2D.position = -RayPosition
	self.scale.x = -1
	motion.x = 100
elif right == false:
	$RayCast2D.position = RayPosition
	self.scale = 1

The $RayCast2D was i fixed the issue but this would cause the same problem.

motion = move_and_slide(motion, up)
	motion.y += 20
	if Input.is_action_pressed("ui_right"):
		self.global_scale.x = -4
	if Input.is_action_pressed("ui_left"):
		self.global_scale.x = 4

This was for testing purpose which caused the same issue.

TheGreatButtby | 2018-10-24 13:53

elif right == false:
    $RayCast2D.position = RayPosition
    self.scale = 1 #should not be self.scale.x?

gtkampos | 2018-10-24 18:27

It should be but that doesn’t change,

 if Input.is_action_pressed("ui_right"):
        self.global_scale.x = -4
    if Input.is_action_pressed("ui_left"):
        self.global_scale.x = 4

so that’s not it.

TheGreatButtby | 2018-10-24 19:11

Which type of node are you scaling? Can you reproduce this with a minimal scene?

Zylann | 2018-10-25 12:56

The node that I’m scaling is a KinematicBody2D. The minimal scene would be were I set the inputs to assign the scaling.

 if Input.is_action_pressed("ui_right"):
        self.global_scale.x = -4
 if Input.is_action_pressed("ui_left"):
        self.global_scale.x = 4

Pressing left doesn’t change the direction and pressing right will change the directions rapidly.

TheGreatButtby | 2018-10-25 14:00

Is that your code really?

if Input.is_action_pressed("ui_right"):
        self.global_scale.x = -4
 if Input.is_action_pressed("ui_left"):
        self.global_scale.x = 4

# Are not they INVERTED? 
if Input.is_action_pressed("ui_right"):
        self.global_scale.x = 4 # since "ui_right" is positive?
 if Input.is_action_pressed("ui_left"):
        self.global_scale.x = -4

gtkampos | 2018-10-25 15:58

The Sprite and Ray is facing left to start with so scale.x = -1 would be right.

TheGreatButtby | 2018-10-26 06:31

:bust_in_silhouette: Reply From: TheGreatButtby

I found out the issue. There seems to be a issue with the function move_and_slide being called and assigning the x value. It probably has to do with how move_and_slide handles scale with direction.

:bust_in_silhouette: Reply From: Hyper Sonic

For those have issue purely with negative scale on X (not physics-specific issues), see my answer on https://forum.godotengine.org/92282/why-my-character-scale-keep-changing?show=146969#a146969

To sum up, scale.x = -1 is converted into scale.y = -1 and rotation_degrees = 180, but scale.x remains 1 internally, so next time you set scale.x = -1, it will try to flip again.

So the issue is about negative scale.x, which is 1 instead of the expected -1. This may give the impression that scale.x is multiplied by -1, but the test code suggested above with -4 and +4 should clearly show that it’s not multiplying, else you’d have your sprite getting bigger and bigger.