godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.12k stars 77 forks source link

Add a `rotate_and_collide/slide` method to KinematicBody #364

Open ligazetom opened 4 years ago

ligazetom commented 4 years ago

Describe the project you are working on: Top down project with non-symmetric shape for kinematic body. (Just some fun with physics so far)

Describe the problem or limitation you are having in your project: Having rectangle as collision shape. If I stay in one place and want to only rotate the pawn, I need to check for collisions as well, not only when moving.

Describe how this feature / enhancement will help you overcome this problem or limitation: It will help many more people, as they won't have to implement the method (which should already exist) on their own.

Show a mock up screenshots/video or a flow diagram explaining how your proposal will work: image

When would I rotate in place setting transforms, I should collide with the red block.

Describe implementation detail for your proposal (in code), if possible: In physics_body.cpp, where KinematicBody is implemented I see that every method is basically using test_move() and only after that setting the positions. So why not do the same for rotations? test_move() or rather PhysicsServer::get_singleton()->body_test_motion() takes Transform as argument so it would not be problem.

If this enhancement will not be used often, can it be worked around with a few lines of script?: Not really, I mean it might be a few lines, but as it would be used very often I believe it should be implemented as those lines are not "that" easy to implement right off the bat.

Is there a reason why this should be core and not an add-on in the asset library?: It is basic feature. Definitely should be in core.

I can implement it myself no problem. The thing is I have no idea how to create bindings for it. So if someone would help me with those (help, not make them without me as I would like to be able to do it in the future myself) then it would be really quick.

Janders1800 commented 4 years ago

Id like to see this done but I have some questions. Will the KinematicBody get pushed back (I personally prefer this one)? CharactRot Or use the collision point as a lever? PhysRot Will this depend on the friction set on the physics material it collides to (It is a KinematicBody so I hope not)?

If a character is using a box as a collider, how it will behave on uneven floors? Will it rotate from the corner is actually touching the floor or from its center (I prefer the center)?

ligazetom commented 4 years ago

Well, this is exactly the thing everyone should be able decide themselves. I would start by rotate_and_collide to see how it works and then move on to rotate_and_whatever. But since I don't know how to create bindings, so I could call them from C++ plugin, I cannot really do much right now.

Xrayez commented 4 years ago

The current move_and_collide/slide take linear velocity for movement:

godot-move-kinematic

How about adding something akin to angular_velocity parameter as well? Kinda feels wrong having to jump between rotate/move methods, especially when linear motion and rotation can happen within one physics frame.

Adding yet another parameter for this to the current API would make it more difficult to use though. I'm not sure why kinematic body didn't replicate rigid body API where linear and angular velocities are just properties. A lot of parameters could be rewritten as properties actually. But things like delta could remain as parameter: godotengine/godot#33653.

I'm fine resetting those properties to whatever initial state as long as it's consistent with rigid body API and easy to use.

Somewhat related to godotengine/godot#13349 from the other side of a coin.

vesk4000 commented 4 years ago

I think we definitely need something like this and also a test_rotate(). But for now, is there a workaround? Why isn't test_move() working, when it takes a Transform2D? I'm having some real trouble with this.

Anudin commented 4 years ago

I'm interested in a workaround too. Since there is no huge outcry for this feature my guess is that there has to be something that I'm overlooking.

Zylann commented 2 years ago

I'm making a game in which players can construct things. In physic terms, a construct is a set of bodies connected with joints. For creative freedom and performance, I'd like to try kinematic joints instead of physically-based ones, and let bodies within the same construct overlap. Unfortunately, without kinematic angular sliding I cannot make them properly collide and push back the construct if it collides with another construct, for example: image Still researching how to achieve this, for now I'm considering to make joints constraints-based (which however means going through physic sim). I'm not necessarily looking for something accurate though, maybe just relying on depenetration forces could be enough. But I figured it could need sliding helpers from the physics engine.

PLUkraine commented 2 years ago

Really miss this one, hope that it's going to be implemented

Calinou commented 2 years ago

@PLUkraine Please don't bump issues without contributing significant new information. Use the :+1: reaction button on the first post instead.

Frontrider commented 2 years ago

To me looks like calling rotate_y and alike on a KinematicBody before move_and_collide creates the desired effect (you get pushed out of a wall as you turn), but it is not enough to cover all cases we can have.

me2beats commented 2 years ago

well, if there will be move_and_slide, rotate_and_collide, then what about scale_and_slide?

reduz commented 2 years ago

The problem with this is that you would need to do a convex cast while rotating and this is near impossible mathematically (and I Can't think of any way to approximate it), so its most likely impossible that this will ever happen.

If you want to be able to do these things, I think it makes more sense to use a dynamic character controller and let it recover with the rotation.

me2beats commented 1 year ago

can quaternions help implementing this?

AThousandShips commented 1 year ago

can quaternions help implementing this?

I'm not sure what you mean? The engine had these back then too, and while rotating through the steps can be done the convex cast issue still remain arguably

Zshandi commented 2 months ago

Can someone please explain to me why this would be different from how the physics with RigidBody is calculated? If the RigidBody physics calculation handles collision detection with both angular and linear velocity (including only angular) without doing the "convex cast while rotating", then how does it detect the collisions of rotating objects? Could we have this method follow a similar process of detecting collisions with rotation?

Note that I've also only just learned what a "convex cast" is, and was having trouble finding much info on it, so I don't know exactly how they work. From what I gather, it is the process of sweeping out the shape to detect collisions. Perhaps I just wasn't searching the right terms, or there just isn't must material on it, but I would appreciate if someone could point me at some resources so I can learn more about how convex casts work.

Frontrider commented 2 months ago

Can someone please explain to me why this would be different from how the physics with RigidBody is calculated? If the RigidBody physics calculation handles collision detection with both angular and linear velocity (including only angular) without doing the "convex cast while rotating", then how does it detect the collisions of rotating objects? Could we have this method follow a similar process of detecting collisions with rotation?

Character bodies interact with physics differently from rigid bodies.

If you want to be able to do these things, I think it makes more sense to use a dynamic character controller and let it recover with the rotation.

This is probably the answer, if my solution does not cover it for you. Also, you don't always need to rotate the body itself, you can design your character to use a rotating sprite.