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

Unexpected behavior when setting negative scale in KinematicBody2D #24663

Open
Tracked by #45334
DragonFrai opened this issue Dec 30, 2018 · 12 comments
Open
Tracked by #45334

Unexpected behavior when setting negative scale in KinematicBody2D #24663

DragonFrai opened this issue Dec 30, 2018 · 12 comments

Comments

@DragonFrai
Copy link

DragonFrai commented Dec 30, 2018

Godot version:
3.1-4a mono

OS/device including version:
Linux Mint 19.1

Issue description:
You try to set the scale.x < 0 for KinematicBody2D, RigidBody2D, and (possibly) StaticBody2D from code, scale changes sign to opposite (-1, 1) -> (1, -1); (-1, -1) -> (1, 1). In this case, the scale actually changes, but the resulting scale is not correct.

In the attached project in _Ready, we change the original scale (1, 1) to (-1, -1). The body changes its scale, but the scale in _physics_process is now (1, 1).

Minimal reproduction project:
KinematicScale.zip

@timoschwarzer
Copy link
Contributor

Please describe "strange behavior" more in detail. (Maybe with a video/GIF, https://github.com/phw/peek)

@DragonFrai
Copy link
Author

DragonFrai commented Dec 30, 2018

    if (Input.IsActionPressed("ui_left"))
    {
        Velocity.x = -WalkSpeed;
        
        if (_animPlayer.GetCurrentAnimation() != "move")
            _animPlayer.Play("move");
        
        var scale = Scale;
        if (scale.x > 0)
        {
            scale.x = -1f;
            Scale = scale;
        }
    }
    else if (Input.IsActionPressed("ui_right"))
    {
        Velocity.x = WalkSpeed;
        
        if (_animPlayer.GetCurrentAnimation() != "move")
            _animPlayer.Play("move");
        
        var scale = Scale;
        if (scale.x < 0)
        {
            scale.x = 1f;
            Scale = scale;
        }
    }

2018-12-30 21-37-18.flv.zip

@timoschwarzer
Copy link
Contributor

I think this code sample is not the problem's source. (At least didn't find anything yet)
But I wonder why you get and set the Scale property instead of just setting Scale.x...

@DragonFrai
Copy link
Author

DragonFrai commented Dec 31, 2018

About Scale.x
default

Here's a simpler example. Perhaps this is documented behavior KinematicBody2D (I have not tested other objects).

default
default
default
default
default

The screenshots show that once the Scale.x < 0, then x and y change their sign.
This project contains only 1 script and only nodes in the main scene.
The first call to _Physics Process Scale remains true, but the first call to _Process Scale has already changed.

Godot version:
3.1-4a mono

OS including version:
Linux Mint 19.1

Mono version:
5.12.0.301

msbuilde version:
Microsoft (R) Build Engine version 15.6.0.0 ( Thu May 10 14:00:26 UTC 2018) for Mono

@Zireael07
Copy link
Contributor

I don't think we're supposed to set negative scale, ever.

@DragonFrai
Copy link
Author

I still think it's weird that the Sprite for negative scale is supported, and for KinematicBody2D no. And when you set the scale in the editor, the body flips, but the scale remains positive in the code. But why scale negative only if scale.x < 0, by y the scale changes and remains the same?

The examples actually change the scale of the sprites. My mistake. I apologize if this is really the correct KinematicBody2D behavior

@timoschwarzer
Copy link
Contributor

timoschwarzer commented Dec 31, 2018

@Zireael07: partially true.
Setting negative scales is just fine in most cases. But: Scaling bodies, areas and collision shapes in general is bad and not intended. You should only scale the Sprite and not the whole body.

@DragonFrai DragonFrai changed the title Wrong SetScale () Wrong SetScale() in KinematicBody2D Dec 31, 2018
@DragonFrai
Copy link
Author

Godot version:
3.1-4a mono

OS/device including version:
Linux Mint 19.1

Issue description:
You try to set the scale.x < 0 for KinematicBody2D, RigidBody2D, and (possibly) StaticBody2D from code, scale changes sign to opposite (-1, 1) -> (1, -1); (-1, -1) -> (1, 1). In this case, the scale actually changes, but the resulting scale is not correct.

In the attached project in _Ready, we change the original scale (1, 1) to (-1, -1). The body changes its scale, but the scale in _physics_process is now (1, 1).

Minimal reproduction project:
KinematicScale.zip

@timoschwarzer
Copy link
Contributor

Related: #5734

@DragonFrai
Copy link
Author

DragonFrai commented Dec 31, 2018

move_and_slide does inverts the KinematicBody scale. But does it only at scale.x < 0. If scale.y < 0 then nothing changes.

Initially, the body has a scale of 1, 1
default

In _ready, the body is reflected horizontally and stretched 2 times. The scale is changed to -2, 1
default

move_and_slide changes the scale of the body to 2, -1. But: visually and physically the body has a scale of -2, 1
default

@timoschwarzer
Copy link
Contributor

timoschwarzer commented Dec 31, 2018

@VAVUS7 yes, that's intended.
Quoting @reduz:

This is intended, because physics bodies manage their own transform which overwrites the ones you set.

That's probably not going to change soon.

So: Don't scale physics bodies.

@DragonFrai
Copy link
Author

DragonFrai commented Dec 31, 2018

But the effect of manual scaling remains. And it is confusing. And again, why only with scale. x <0? Physical synchronization in KinematicBody simply sets the scale to 1, 1.

@akien-mga akien-mga changed the title Wrong SetScale() in KinematicBody2D Unexpected behavior when setting negative scale in KinematicBody2D Jan 27, 2020
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

4 participants