-
-
Notifications
You must be signed in to change notification settings - Fork 21.1k
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
KinematicBody/2D uses any combination of layer-mask for move_* collision detection #15243
Comments
The same happens with KinematicBody (3D) with any physics engine. The same project with 3D example: |
I don't think this is a bug and it makes sense that there's a collision but it's not that the KinematicBody doesn't care about layers/masks when using KinematicBodies (or any body) respect the layer/mask setup as long as it makes sense. If you don't want your KinematicBody to collide with anything that's checking layer 2 (its layer 2 mask is enabled) then don't set your KinematicBody layer to 2. |
@mrcdk if body with the corresponding mask is not moving, it cannot collide, if it does it should emit a signal at least. This also limits some usage of the KB, where you do want to ignore some bodies (not on mask) and obstruct these at the same time while using move. |
It doesn't matter if it moves or not. A collision happens between a pair of objects and each object will test their layer/mask combinations because the physics server doesn't know if object A was creating the collision with B or B was creating the collision with A. (AFAIK this is normal in any physics engine it's not a Godot only behavior) Example:
I'm not sure what do you mean here. What signal? Who should emit a signal?
Do you mean that you want to collide only when you aren't moving the KinematicBody? In that case I guess you will need to enable or disable the layer/mask bit when moving. |
The body that expects a collision (the one with a mask, that are used for that reason) should emit a signal if hit a body that do not expect one (without mask). You have a moving wall that ignores a character, but is stopped by other walls, on the current state it cannot use move for collision because will be stopped by the character and disabling layer is not an option in that case because will be ignored by the character. But if this is the intended behavior, it should be documented (like with areas) and masks may need to be disused for removal in the future, because the usage brings more confusion to users than what they offer (with only layers again it will make more sense). |
I guessing you have it setup it like (I'm using names here):
Which makes sense. A static wall will collide with a character (although this doesn't matter because a static wall doesn't care about that. It's not actively looking for collisions) and a character will collide with a wall. But you are adding a third variable, a moving wall that will still collide with other static walls and that will not collide with a character. You have two options here:
Using your example, when connecting the
I don't think an API is broken or useless and should be removed just because I don't understand how to use it or how it works. Sometimes it's broken and or useless and it's a pain to make sense out of it don't get me wrong, but not in this case. Collision filtering using layers and masks is a common thing in any game/physics engine. If this needs better documentation or not I'll let others decide. |
Collision exception works but may be too complex in some setups when it could be managed by a one direction detection made by the corresponding mask (and the other body can have its mask too if need 2 direction). |
This seems to still be a problem in 3.1, I'm trying to make a solid character stop the player but the solid character is not supposed to be stopped by the player which is impossible at the moment without using exceptions which I can't really use in this particular case, I already tried every layer and mask combination but nothing works. |
This is really annoying. Seems that |
Patched the engine for myself meanwhile, please try this one. Seems to work properly. |
@V0idExp I think it is the other way around, That is also used in body pair and area pair so probably the behavior of that method is correct, having the option of getting notified only one on the pair may be better. |
I thinked about it this way: object 'this' should check whether it collides with someone and be notified for such cases. And it fits pretty well and intuitevely for cases such as the following. |
I would use (collision_mask & p_other->collision_layer) != 0. The way I see it is that if an object has a mask set for example layer 3 and 4, it will collide with any object in layer 3 or 4 |
The expression proposed above doesn't seem to work, collision signals aren't triggered on objects which I expect them to be, and weird stuff happens, although I can't see right now why :| |
@V0idExp I think this might be the issue that I’ve run into. I was prototyping a tower defense game where all the enemies are kinematic bodies, on layer 1 and mask set to layer 2. when I spawn the enemies and they overlap one another, my collision pairs go through the roof and my frame rate drops because of the number of collisions that are being checked, even though they should be ignoring each other. did your solution above from July 21 seem to correct the issue for you? I’m really enjoying godot but started looking at other engines when I encountered this issue. |
Hi! Yes, for my case it did the job and apparently didn't break normal
behavior.
…On Sat, Nov 16, 2019, 06:58 Robby Campano ***@***.***> wrote:
@V0idExp <https://github.com/V0idExp> I think this might be the issue
that I’ve run into. I was prototyping a tower defense game where all the
enemies are kinematic bodies, on layer 1 and mask set to layer 2. when I
spawn the enemies and they are overlap one another, my collision pairs go
through the roof and my frame rate drops because of the number of
collisions that are being checked, even though they should be ignoring each
other.
did your solution above from July 21 seem to correct the issue for you?
I’m really enjoying godot but started looking at other engines when I
encountered this issue.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#15243?email_source=notifications&email_token=AAERJGSEF2VHNLE4TP2RCWLQT5VUVA5CNFSM4EKAMWL2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEEHIX5Y#issuecomment-554601463>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAERJGVFYVFUMHDES4JFBZDQT5VUVANCNFSM4EKAMWLQ>
.
|
@V0idExp You might want to repost your patch on Godot Proposals (or submit a PR here, either way.) Frankly, the original behavior seems more like a bug than a feature, so it's probably worth trying to push this upstream. |
I agree that it seems like a bug, but maybe they would consider adding an option to the project settings to allow you to choose which behavior you want for your project. |
I think a single flag within the kinematic body would be good enough (only accessible through gdscript so that it weeds out people who don't know what they're doing?) |
Apprently, in 3.2.1 the bug does not reproduce anymore. |
@V0idExp still happens between KinematicBody2D bodies, but the behavior with rigids is different (it does not stop but move the rigid instead) which makes everything less consistent now. |
I have made another test to be sure, and the change of behavior with rigids is due to infinite inertia being default on true, if it is set to false, the KB still stops against a rigid body that should not be detected (even sleeping bodies). |
I'll try to take a look once again these days, finally got some time for
some indie gamedev.
…On Mon, Apr 13, 2020, 14:22 eon-s ***@***.***> wrote:
I have made another test to be sure, and the change of behavior with
rigids is due to infinite inertia being default on true, if it is set to
false, the KB still stops against a rigid body that should not be detected
(even sleeping bodies).
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#15243 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAERJGTLT6CELWMFIR6HQ2LRMLYWFANCNFSM4EKAMWLQ>
.
|
The question is: if the KB is to ignore the RB, but the RB mask includes the KB layer, should the RB be moved by the KB? It would be probably a flexible feature, since you can have a projectile KB being shot and just place it on "projectiles layer", and all enemies will have that layer in their mask to be affected by it, without the need of the KB to mark explicitly the enemies layer... but that requires some invasive changes of code and I'm not sure that's easily doable, and probably, breaks a lot of existing code. |
I did some research on the workings of the Godot's 2D physics (which roughly, mimics the 3D counterpart, down to the structure, class names and most of the collision checking code): godot_physics_2d.md.pdf I have to agree with @mrcdk , there's no simple way to exclude a collision check of a CollisionObject2D (being it a kinematic, rigid or static body or a collision area) just one way, so it is not notified about the collision, but the collision effects to be still propagated to objects which are interested in being notified about. One can always ignore the result of I'd close this one as not a bug. |
Same for #7644 |
I don't think it ever was a bug, just an unwanted behavior for many, choosing to keep the original less flexible design doesn't sound good to me. |
Then state this behaviour clearly in the documentation please. The current text, clearly says that the body would be ignored if it's not in the layer checked in the mask.
|
Godot version: 3.0 d6a1125, 2.1.4
Issue description:
KinematicBody2D move methods collides against bodies if the other bodies have the kinematic layer on the collision mask, meaning KB is using the layer too, not the mask only for collision resolution.
The expected is for the body to ignore the others that are not in their masks, this issue makes some common setups more complicated than they should, and renders the
move_*
methods almost useless.Steps to reproduce:
move_and_slide
ormove_and_collide
the KB against the other body.Minimal reproduction project:
KBmaskbug.zip
Probably related to #7644
The text was updated successfully, but these errors were encountered: