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

Scaling issue with Rigidbody2D #89898

Closed
Hedgestock opened this issue Mar 26, 2024 · 4 comments
Closed

Scaling issue with Rigidbody2D #89898

Hedgestock opened this issue Mar 26, 2024 · 4 comments

Comments

@Hedgestock
Copy link

Tested versions

  • Reproductible in v4.2.1.stable.mono.official [b09f793]

System information

Windows 10 and 11 - v4.2.1.stable.mono.official [b09f793] - forward+ and gl_compatibility - both vulkan and gles3 - NVIDIA GeForce RTX 4060 Laptop GPU / NVIDIA GeForce RTX 3060 GAMING OC 8G

Issue description

When trying to scale a Rigidbody2D, either nothing happens, or the X component of the scale gets used for both X and Y values.
image

Steps to reproduce

Add a Rigidbody2D to a scene, and in it's script, assign the Scale during the Ready() call.

Minimal reproduction project (MRP)

BugTestScale.zip

@AlexOtsuka
Copy link
Contributor

Hi,

Absolutely fantastic high effort MRP. I believe you swapped the vertical and horizontal labels around, no big deal. The behavior is known, however, as the scale of a RigidBody is intended to be 1 in order not to mess up the physics calculations. Your scale actually gets applied, but is immediately modified by the RigidBody (which is the point of a RigidBody, to let it update the object's transform based on how it was affected by the physics system).

Did you manually set the scale for the second row in the inspector? Those don't get scaled at runtime for me either when running your MRP, everything else is the same however.

More info: #5734, #79929, https://stackoverflow.com/questions/77590667/godot-physics-resizing-my-sprites-at-runtime

@Hedgestock
Copy link
Author

Oh okay, if I'm not supposed to touch the RigidBody scale because it takes care of updating stuff by itself, it leaves me with a question.
I'm developping a fishing game, and up until now, the fishes had centered and symetrical hurtboxes, meaning I could flip the sprite to make them swim in the opposite direction and it would not matter.
However, now we are adding fishes with uncentered hurtboxes (by that I mean CollisionShape2D) and I thought I could just scale the whole fish vertically by -1 to get it to flip, but as you explained and as the issues and the SO thread you linked illustrate, RigidBody is not intended to be used this way.
A fish looks like so:
image
So for uncentered hurtboxes, my hotfix was to do

	public override void _Ready()
	{
		sprite = GetNode<AnimatedSprite2D>("AnimatedSprite2D");
		hurtBox = GetNode<CollisionShape2D>("HurtBox");
		<...>
		sprite.FlipH = flip;
		if (flip)
		{
			Flip(hurtBox);
		}
        	<...>
	}
	
	protected void Flip(Node2D node)
	{
		Vector2 unflipped = node.Position;
		node.Position = new Vector2(unflipped.X * -1, unflipped.Y);
	}

which basically moves the position of the CollisionShape without flipping it.
For unsymmetrical CollisionShapes, I could maybe scale it by itself with (-1,1) in addition of doing the Flip(Node2D node) trick, but the more children the fish gets, the more stuff we have to track and make sure are correctly flipped, so we would really like a solution where we could scale/flip the whole fish and everything within would follow.

We also considered putting every flip-affected children in a Node2D and flipping that as follows:
image
But then "This node has no shape, so it can't collide or interact with other objects." was now an issue on the parent RigidBody.

Do you maybe have an elegant solution to our problem ? Otherwise we'll manage with ducktape-code.

Sorry for the long post, and for mixing vertical and horizontal labels, also, I'd run this on more hardware/settings to figure out why the second row in the debug exe does not scale on your machine at runtime, but on mine yes, but since it's not intended for the scale of a rigidbody to be changed from outside anyways I won't bother ^^

Thanks for your time and for the helpful links !

@AlexOtsuka
Copy link
Contributor

Modifying the scales and sizes of the children nodes is definitely the way to go.

I think the ideal approach is something in between your two ideas:

I'd put everything that needs to be affected inside a Node2D with the exception of the CollisionShape2D node (because those need to be direct children of the CollisionObject2D node for it to function properly) and flip both the wrapper Node2D and the CollisionShape2D at the same time.

@Hedgestock
Copy link
Author

Oh right, I could put everything in a container but the CollisionShape then I'd only have to worry about 2 things, IDK how I did not realise that, I was so focused on making it all work in one go that I missed it.

Thank you again for your thoughtful insights !

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

3 participants