Godot's collision system(s) seem very unintuitive and messy. I can create a character body and a rigid body and give them each collision shapes. Simple enough. It works. They appear to collide. Great. Why can't I access what I collided with? There seems to be no collision signal telling me what I collided with. I apparently have to add an Area2D node and a third collision shape to retrieve that information reliably. get_slide_collision_count() only reports collisions caused by move and slide, not generally signalling a collision occured. And that's just an index,not even the collision event or the entity colliding.
Collision is one of the most fundamental building blocks for game design. It blows my mind that it is so wonky and split across so many systems (physics, gravity, movement, area overlaps) and almost none tell me what I collided with. I have to cast a ray to see if I hit the ground from freefall under gravity but the physics system stopped my movement upon collision so it knows that I’m grounded but won’t inform me directly? Wow. Why? What am I missing? Am I missing anything?
RigidBody2D has both a method for reporting what objects are being collided with (get_colliding_bodies) as well as signals for detecting bodies entering and exiting (body_entered and body_exited).
As for why CharacterBody2D does not have those methods, I don’t know. But I can make an informed guess and say that it probably has to do with the responsibilities of both classes. A CharacterBody is likely to be used for player characters, whereas RigidBody objects are probably used for things that should act on the player. If there’s a trampoline somewhere in a level that should push the player in a certain direction and with a certain velocity based on the angle of incidence and impact speed, then it makes sense to me that it is the trampoline that should detect the player, instead of the player detecting the trampoline.
Without move_and_collide (and therefore move_and_slide) character bodies do not move so they don’t collide with anything, other things can still collide with them, like a StaticBody.
Rigid bodies do emit a body_entered signal.
Collision systems are complex, but what are you trying to achieve that you find yourself hitting blockers on? Something about falling through floors? or not falling through floors, but you want some kind of information?
A kinematic character controller is assumed to always begin in a non-colliding state, and will always move to a non-colliding state.
So it won’t report any collision because it avoids them. They never reach the collision point. Buy you still can access the would-be collisions information that the body avoided with CharacterBody2D.get_slide_collision()
I have yet to find any way to get what is being collided with. It’s as if no collisions ever take place. My setup is simple. Just a way to get a feel for the engine. A player, a falling block, a ground to walk on. Dead simple. Nothing I have tried has ever reported a collision has ever occured. get_slide_collision_count never returns any indexes. Not with the ground, not with the faling block. Not with the block grounded. No player movement ever results in a reported collision. I tried emitting a body_entered signal. It never emits from the block. I tried an area2d on the block. Nothing emitted. From what I can tell, even following tutorials to a T, Godot simply dies not report what was collided with under any circumstances. Yes, everything is setup correctly. Yes, they’re all on mask and collision layer 1. Yes, monitoring is enabled. Monitored enabmed. Nothing disabled. No other scripts. Just a simple acene and no feedback from an engine clwarly showing graphical collisiona taking place but never relaying what collided to me so I can mak gam. I’m extremely leery kf Godot now because this is game-dev 101 and it doesn’t even report collisions without massive issues. How is a complex system going to fare? I have strong doubts that it would fare well now rhat I see what Godot struggles with.
I can’t really comment on RigidBody2Ds since my games never used them, but I can talk about CharacterBody2D a bit.
In almost all my games, collisions for me are handled by the is_on_floor, is_on_wall and is_on_ceiling methods, which are plenty enough in almost every single case for me.
In the few cases where I needed something extra, I simply stuck a raycast on the body itself, and enable / disable it whenever needed, so it’s not constantly checking for collisions when I don’t need it to.
I have tried movement collision methods for retreiving the collided body. They don’t work when one is the CharacterBody2D and the other is a RgidBody2D. At least, I have found no way to get these function to return anything at all regardless of what is bumped into. I suspect the RigidBody2D’s collisions are silently handled by the physics internally and so CharacterBody2D never actually colides with it and never informs me of what collided.
Even ataching an Area2D just below the block’s own collision bounds (to detect collisions from below) fails to emit a body_enter signal even though I can visibly see the debug collision shapes overlap in runtime. It doesn’t emit the signal when the player’s CharacterBody2D enters the area2D of the RigidBody2D. I am at a loss as to why.
People are telling me not to use CharacterBody2D and to use RigidBody2D instead because collisions aren’t reported between kinematic and physics objects reliably, or in my case, apparently at all.
Is there another way to get that information? Is there some setting I overlooked? I’ve scoured the web, YouTube, this forum and I can’t find any solution. It’s as if collision detection doesn’t occur even though I can see it occurring visually on-screen. The player and block do collide but none of the methods to detect the collision, that I have tried, return any results.
Have you checked RigidBody2D’s Contact Monitor and Max Contacts Reported properties? Set them to true and at least 1. By default Contact Monitor is false.
I think that may have been the issue. I ended up deleting and then re-creating the project from scratch. I did set those parameters this time around, max set to 5. Now I do detect the player entering the area2D of the rigidbody2d as expected. I must have missed them in my first attempt. I’m going to mark this as solved. Thanks to everyone for helping me grok code. Cheers!