Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KinematicBody2D move_and_slide() transforming the scale of the object #21849

Closed
JoeshuaBaker opened this issue Sep 7, 2018 · 20 comments
Closed

Comments

@JoeshuaBaker
Copy link

**Godot version:**v3.0.6 stable.official.8314054

**OS/device including version:**Windows Version 10.0.17134 Build 17134

Issue description:

Tried to flip sprite by applying scale.x = -1, but after move_and_slide() is called the scale.x becomes scale.y scale.x is set to 1.

Steps to reproduce:

  1. Make KinematicBody2D
  2. Attach Sprite to it
  3. in physics_process(), change scale.x = -1
  4. call move_and_slide() with UP vector (0, -1)

Minimal reproduction project:

Test_Project.zip

@eon-s
Copy link
Contributor

eon-s commented Sep 8, 2018

You should not scale bodies, the physics server will reset the node scale to match the state scale (and it takes 1 only).
Flip the visual representation (sprite in this case) not the body.

@zydeas
Copy link

zydeas commented Sep 8, 2018

Any idea if this is going to be implemented in 3.1? This seems like something the physics system should support.

@eon-s
Copy link
Contributor

eon-s commented Sep 8, 2018

@zargy 3.1 won't let you scale shapes and probably bodies either, at least with the editor.

Body scale support could be nice to have (at least a fake one that just resizes the shape) but may need some work on the physics part to support it correctly, in particular if there are different scales on a scene along a single branch of the tree.

@Piet-G
Copy link
Contributor

Piet-G commented Sep 8, 2018

It would be REALLY useful to be able to scale bodies.

@groud
Copy link
Member

groud commented Oct 2, 2018

I'll close this as a duplicate of #5734. And specif it also applies to Kinematic bodies

@groud groud closed this as completed Oct 2, 2018
@groud groud added the archived label Oct 2, 2018
@groud groud reopened this Oct 2, 2018
@groud
Copy link
Member

groud commented Oct 2, 2018

Sorry, it's not the exact same problem. As the linked issue does says that kinematicbody2D is not affected directly.

@JosephVoid
Copy link

If the move_and_slide() function keeps resetting the scale of the kinematicBody2D it's going to be difficult to flip rigged/skeletal nodes, being that the only way i found to flip them is through KinematicBody2D.scale.x = -1.

@fasihrana
Copy link

Being asked to flip everything inside rather than flip the KinematicBody2D is a bit much. Just ran into this issue aswell.

@aaronfranke
Copy link
Member

aaronfranke commented Jul 31, 2020

This is not a KinematicBody2D problem, this is a Node2D limitation. Duplicate of #17405.

The symptoms are different, but the cause is the same: Negative X scales can't be decomposed from a transformation matrix, and negative X scales get encoded in the transformation matrix as a rotation, therefore negative X scales have problems like these and should be discouraged or disallowed.

#37376 adds a warning for when this happens.

@ghost
Copy link

ghost commented Jul 31, 2020

Therefore negative X scales have problems like these and should be discouraged or disallowed.

@aaronfranke Negative scaling for mirroring complex scenes is incredibly useful. Saves us untold amounts of animation work.

@aaronfranke
Copy link
Member

What about if you just animated the X vector of the transformation matrix, or even just a simple number, then constructed a transformation matrix with (x, 0, 0, 1, 0, 0)?

@ghost
Copy link

ghost commented Aug 1, 2020

What I'm describing is done through the inspector scale property, usually done by an artist using the AnimationPlayer.

The typical use case for them is animating actors with dozens of parts, and mirroring directions by inverting the scale of a root node.

@eon-s
Copy link
Contributor

eon-s commented Aug 1, 2020

Yes, this is a serious limitation of physics bodies, because mirroring a full scene with bodies also need to affect offsetted shapes, this kind of thing is a common basic 2D game dev practice.

@RCastroAB
Copy link

After some serious debugging to find out what was silently changing the scales of my objects before finding this thread, I believe there should at least be some warning when calling move_and_slide on scaled bodies to avoid some further confusion.

@aaronfranke aaronfranke closed this as not planned Won't fix, can't repro, duplicate, stale Jul 28, 2022
@agrimminck
Copy link

Is this topic closed? I am too running into an issue here, I'd have to duplicate all my animations to fit the characters to go left and right, when I just could do a scale.x = -1. That would be nice!

@agrimminck
Copy link

agrimminck commented Dec 3, 2022

I found a solution to this! It works with animationPlayer!
Node2D.transform.x *= -1.0

@gamenerds
Copy link

gamenerds commented Jan 27, 2024

Just to add to this - ran into this (rip 2 hours) and while I now understand how things ARE, I absolutely cannot understand why this should be the expected behavior. Manually flipping every part of CharacterBody2D is extremely cumbersome and the engine should absolutely let us do this with a single line of code. In general, if I as user set a property, I don't expect the engine to change it - this goes for any property ever. So any code that violates that is, in my opinion, bad code that we should aim to fix.

Meanwhile using @agrimminck's workaround above with transform.x - ty sir.

@aaronfranke
Copy link
Member

@gamenerds The property for transforms is the transformation matrix. Rotation and scale are friendly wrappers provided on top of this property. Godot went with the convention of flipping Y instead of flipping X when decomposing the scale from the transformation matrix. You may keep track of the rotation and scale separately in your code, but physics engines usually need to work with the full transformation matrix of the object.

@gamenerds
Copy link

Thank you, @aaronfranke, it makes sense, but imho also irrelevant. If the engine has a writeable property, it should simply work, and as a user I couldn't care less how. Or it should be read-only. This is true for every other property so it's confusing (and wastes so many hours across countless developers) when one property suddenly behaves differently in a specific scenario (physics objects) when it works just fine in other scenarios (area2d for example).

Another (less ideal) solution is to document this in every affected method (scale property, move_and_slide function, etc.) instead of having people search in frustration until they stumble on this thread.

@Godeaux
Copy link

Godeaux commented Jun 24, 2024

for any future people such as myself who find this, it was slightly painful, but creating a new "DirectionNode" Node2D and reparenting everything that I needed to have "left or right" facing directionality from the player, and then just doing the standard

#If player is holding left and right down, maintain direction
	if Input.is_action_pressed("left") and Input.is_action_pressed("right"):
		pass
	#If player presses right, face right
	elif Input.is_action_pressed("right"):
		direction_node.scale.x = abs(direction_node.scale.x)
	#If player presses left, face left
	elif Input.is_action_pressed("left"):
		direction_node.scale.x = -abs(direction_node.scale.x)
	#Else, maintain direction
	else:
		pass

This worked for me, including animation player, off-centered sprites, etc. Hope this helps someone :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests