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

Allow RigidBody to inherit a moving parent Spaital's transform. #22904

Closed
aaronfranke opened this issue Oct 10, 2018 · 25 comments
Closed

Allow RigidBody to inherit a moving parent Spaital's transform. #22904

aaronfranke opened this issue Oct 10, 2018 · 25 comments

Comments

@aaronfranke
Copy link
Member

aaronfranke commented Oct 10, 2018

Godot version: Occurs on 3.0 to 3.2 and above

OS/device including version: Linux Xubuntu 18.04 64-bit (but should affect all OS and devices)

Issue description: Currently, RigidBodies can't have a parent that moves. When I try, it glitches. I need this functionality for my game. This functionality is present in Unity (which I've used before) and I've provided a video below which shows the functionality working in Unity and not working in Godot.

https://www.youtube.com/watch?v=5PCMQZxs2cg

This has been reported as a bug before (#14337) and it was closed due to this functionality not being intended, so I'm opening this issue as a feature request instead. Please add this functionality!

Steps to reproduce: Create a Spatial parent node with a RigidBody child node. Try to move or rotate the Spatial and RigidBody nodes at the same time. It flickers like crazy. Ideal result: It doesn't flicker.

Minimal reproduction project: There is a reproduction project linked in the original issue, here it is: https://github.com/godotengine/godot/files/1536902/Godot3Bug.Bullet.Engine.zip

@groud groud added this to the 3.1 milestone Oct 10, 2018
@aaronfranke aaronfranke changed the title Allow RigidBody to inherit a parent Spaital's transform. Allow RigidBody to inherit a moving parent Spaital's transform. Oct 10, 2018
@QbieShay
Copy link
Contributor

QbieShay commented Oct 14, 2018

@aaronfranke Godot has different paradigms from Unity and Unreal.
Please, when reporting an issue explain what you need to achieve and why you can't achieve it.
Saying "this is in Unity and i need it for my game" doesn't give enough information to understand the scope of the issue :)

EDIT: Are you using the is_kinematic flag in Unity?

@QbieShay
Copy link
Contributor

@groud this should not be flagged as bug, as it is intended behaviour

@LikeLakers2
Copy link
Contributor

LikeLakers2 commented Oct 14, 2018

My own use-cases for a RigidBody would be for objects that should not completely follow physics, but still need to move (i.e. a moving platform), even if through following the parent's transform. If I want a object that I wouldn't be moving, I'd use a StaticBody. Ignore this, I'm remembering my Bodies wrong. That being said...

I'm not sure I could consider that intended behavior. Nodes with transforms almost always inherit their parent's transforms -- why is it that RigidBody is the exception? How can you consider that intended behavior when it's the odd one out?

@QbieShay
Copy link
Contributor

@LikeLakers2 the behaviour you described is available with KinematicBody. RigidBodies are "owned" by the physics server na dyou should not move them on your own. If you really need to move a rigidbody you can use the _integrate_forces function, but only if you know what you are doing.

@LikeLakers2
Copy link
Contributor

Ignore that bit about behavior, I've been remembering my Bodies wrong. That being said, we're not moving them on our own -- we're wanting them to inherit the parent's transform. At the very least, if this is intended, it probably shouldn't flicker.

@QbieShay
Copy link
Contributor

@LikeLakers2 I understand, but in this case you are misusing a rigidbody. KinematicBody is what you are looking for :)
As for the flickering, I don't think it can be solved easily, as you are basically fighting with the physics server for who should move that body

@aaronfranke
Copy link
Member Author

aaronfranke commented Oct 14, 2018

@QbieShay The use case is to have a RigidBody player object which is a child of a moving platform. I need to keep the player moving with the platform, but also able to move around on it.

Using a Spatial or KinematicBody for the player won't work because my game takes place in space and the player needs to be able to freely move around and collide with things.

@QbieShay
Copy link
Contributor

@aaronfranke why is KinematicBody not suited? it does collide.

@groud groud removed the bug label Oct 14, 2018
@groud
Copy link
Member

groud commented Oct 14, 2018

@groud this should not be flagged as bug, as it is intended behaviour

Indeed, this is more a discussion topic. Thanks!

@aaronfranke
Copy link
Member Author

@QbieShay When I set my player to Kinematic, my player doesn't move at all with AddCentralForce. And if I just use Translate it phases through colliders as if they were nothing.

The problem, as I stated, is that RigidBodies don't inherit the parent transform.

@QbieShay
Copy link
Contributor

Kinematic body needs to be moved with move and collide or move and slide in the physics process, if you change the transform it goes through objects.

@aaronfranke
Copy link
Member Author

@QbieShay Ok, I didn't know that, since it's only available with KinematicBody and not RigidBody set to Kinematic. But it doesn't seem to behave correctly, it slides against the direction of rotation when I tell it to move_and_collide towards the floor on my rotation parent object. And even if that did work, it doesn't do what I want, I need players to have velocity.

Back to the original issue then, make RigidBody work with moving parent Spatials, though the slight sliding behavior of KinematicBody should also be looked into.

@QbieShay
Copy link
Contributor

QbieShay commented Oct 15, 2018

Velocity can be emulated via code. I still do not understand the full problem.

I believe it could be interesting for you to take a deeper look into KinematicBody, I don't see this feature of rigid body implemented anytime soon anyway: it would be possibly breaking a huge amount of existing games, plus, the control of rigid body belongs to the physics server by design.

@tagcup
Copy link
Contributor

tagcup commented Oct 15, 2018

I don't exactly see why the Bullet's control over RigidBody instances and having a spatial parent are mutually exclusive.

The only thing Bullet requires is that it needs to use global transform of bodies during each integration step. One can simply pass the global transform of the object to Bullet, get the updated transform, "subtract" the parent node's transform from it (meaning left-multiply with parent's inverse transform) and assign the remainder to the RigidBody. I'm guessing this is what happens with old bindings since it works.

This is all assuming that the parent object can't move between pre- and -post-integration, which I believe would be the case if the parent spatial is only moved during physics process.

@QbieShay
Copy link
Contributor

@tagcup this change would probably break countless games.

@tagcup
Copy link
Contributor

tagcup commented Oct 18, 2018

@QbieShay 1) That doesn't change anything at all if you don't have a Spatial parent. 2) That's actually how it is supposed to work.

Bullet doesn't have any such restrictions since all objects have global transforms, and isn't aware of the nested object hierarchy in Godot. This conversion needs to be mediated by the new Bullet / old "GodotPhysics" bindings. As long as it is done properly (as I described above, which is a proper way of handling the transform tree, and not a hack), it should work.

My guess is the new Bullet bindings is mishandling local -> global (for bullet) -> local conversion sequence at some point. This apparently works with the old GodotPhysics bindings to modified old Bullet.

@QbieShay
Copy link
Contributor

@tagcup

  1. Assuming that people don't have spatial parents to rigidbodies is dangerous. I would brand this change as compatibility-breaking.
  2. I am not so deep into bullet so i trust you on that :) @AndreaCatania can probably give good insights on this

@AndreaCatania
Copy link
Contributor

Here is where the global transform is set:
https://github.com/godotengine/godot/blob/master/modules/bullet/collision_object_bullet.cpp#L191

I receive the global transform directly from godot. I don't perform any operation like conversion from global to local or vice versa.

@tagcup do you think there is a better way to handle it?

Also, even if it would work perfectly, the best thing to do is to make the physics engine take care of the rigid body. So as said before: #14337 (comment)
This feature request is a discouraged approach.

Why? because by changing transformation you could potentially teleport the rigid body inside another object making it stuck inside it.

So @aaronfranke implement such think is possible but require a bit of work from your side. Basically what you have to do is to take care of ground velocity.

@tagcup
Copy link
Contributor

tagcup commented Oct 18, 2018

I receive the global transform directly from godot. I don't perform any operation like conversion from global to local or vice versa.

That sounds like the problem

Why? because by changing transformation you could potentially teleport the rigid body inside another object making it stuck inside it.

You can do that using a plain KinematicBody as well, without any spatial nodes

@tagcup
Copy link
Contributor

tagcup commented Oct 18, 2018

You can probably check the old bindings reduz wrote to see how the conversion should be done since it works there

@tagcup
Copy link
Contributor

tagcup commented Oct 18, 2018

Here is where the global transform is set:
https://github.com/godotengine/godot/blob/master/modules/bullet/collision_object_bullet.cpp#L191

I didn't mean the part where you pass the global transform to bullet, I meant the part where you get, and update the transform on the godot side. You should be able to use [get|set]_global_transform() helpers for implementing what I mentioned above

@tagcup
Copy link
Contributor

tagcup commented Oct 19, 2018

Ah, I remembered something relevant. The issue might be something else completely; Bullet doesn't allow "teleporting" a rigid body in a straightforward manner (which is what moving the spatial would effectively), but there were workarounds.

In Unity, teleporting a rigid body (that is not kinematic) is exposed to the API, I'm assuming it's not implemented with Bullet?

@samuelpedrajas
Copy link
Contributor

I'm not an expert user of the bullet physics, but since this issue is tagged as discussion, I thought I could give my user experience. I made a simple setup like this:

screenshot_tree

In which Center is a fixed-size Control anchored to the center of the parent. I usually do this to make my game multiscreen and resizable, because everything remains in the center this way. But this is what happens when resizing the window:

physics2

This is because the position of the floor, which is a static body, is updated to follow its centered parent, but the rigid body position is not, so it moves and collides when resizing the window. Same thing happens when making the window horizontally bigger.

Although I was able to find a workaround by using a Camera2D, I felt this default behavior to be unnatural too. I may be missing something important, in which case I apologize in advance.

I attach the project shown in the GIF file:
RigidBodyTest.zip

@aaronfranke
Copy link
Member Author

aaronfranke commented Nov 9, 2019

I suggest bumping this to the 4.0 milestone, there's no way this will be done for 3.2.

I'd love to see an overhaul of the physics system eventually, which might not even happen for 4.0, maybe 4.1 or 4.2 or something. The current physics system has many bugs, and limitations like this issue, and there are also people asking to keep the old physics engine.

@madmiraal
Copy link
Contributor

Feature and improvement proposals for the Godot Engine are now being discussed and reviewed in a dedicated Godot Improvement Proposals (GIP) (godotengine/godot-proposals) issue tracker. The GIP tracker has a detailed issue template designed so that proposals include all the relevant information to start a productive discussion and help the community assess the validity of the proposal for the engine.

The main (godotengine/godot) tracker is now solely dedicated to bug reports and Pull Requests, enabling contributors to have a better focus on bug fixing work. Therefore, we are now closing all older feature proposals on the main issue tracker.

If you are interested in this feature proposal, please open a new proposal on the GIP tracker following the given issue template (after checking that it doesn't exist already). Be sure to reference this closed issue if it includes any relevant discussion (which you are also encouraged to summarize in the new proposal). Thanks in advance!

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

9 participants