I understand that in order to call OnCollisionEnter between two objects (with colliders) one of the objects need to have a non kinematic RigidBody. My player object does not have a Rigidbody but it has a Character Controller. Does this mean that the only way to detect when the player collides with other objects (in code) is that the other object needs to have a RigidBody? My understanding is that RigidBodies are meant to be used for physics simulation. So I feel like I shouldn’t need them just for detecting when my player collides with a stationary object. Is there a better way?
Also I can’t even get OnCollisionEnter to be called when I do add a RigidBody. From doing some Google searching it seems that I can use OnControllerColliderHit. But it only gets called when the CharacterController is moving and it gets called every frame that the controller is touching another collider (instead of when it enters the collision). This is frustrating but I guess I can just keep track of what objects the player is colliding with in order to detect if it’s the first frame that the collision happens. But this doesn’t solve the issue of wanting to detect projectile collisions with the player.
I’m pretty sure a rigidbody is required for two colliders to detect each other. Only one collider needs a rigidbody so that it can detect collisions. So your player can have a rigidbody but walls and platforms doesn’t necessarily need so.
That’s an indirect way of saying that if you don’t add a Rigidbody(2D) then the Collider(2D) are Static meaning not moving. Static colliders don’t contact other Static colliders because why should they; they never move. By adding a Rigidbody(2D) to one of them, it’ll become Dynamic (moving); Dynamic do contact Static colliders.
No, you’re right, this is kinda braindead, but CharacterController does not behave like other colliders, even when striking other colliders. You can use OnCharacterColliderHit on the character but other objects are oblivious to being hit by the CharacterController even though it’s ostensibly derived from Collider.
Here’s a test I just did in 2021.3 LTS.
CharacterController on layer Characters
layer Characters can hit layer Default
Box Collider and dynamic Rigidbody on a separate object on layer Default
(for completeness sake, I will say the dynamic Rigidbody was constrained)
any setting of Contact Pairs, including ALL
this is also true for other configurations, like kinematic Rigidbody, etc.
OnCollisionEnter never called on the Rigidbody
Versus:
add a second Capsule Collider to the character, just a hair fatter in radius
suddenly all the OnCollisionEnter you want is registered on the Rigidbody
And worse:
if your Rigidbody is kinematic, regardless of Contact Pairs, your Rigidbody
still won’t get collisions from that Capsule Collider + CharacterCollider combo
since you’re stuck with a dynamic Rigidbody, that Rigidbody won’t work
well with MoveRotation
ah dang… i followed that, and it doesn’t work. i’m in 3d. i have a rigid body on the player but not on the item i’m picking up. i go through the item but it does not hit the debug log. my player has a character controller but no capsule collider. if i use a capsule collider on the player, it completely messes with the physics and the player rolls down the hill, but it actually does log the collision. why is it not hitting onCollisionEnter on the player when there is no capsule collider but a rigid body and char controller are still there?
damn got the same problem, i want to make a trampoline but my characterController wont detect the collisions. It collides with the object but wont register the collision. The weird thing is when i take my gameObject and drag it manuely (while the game is running) into my characterController it register the collision, it wont do that if i use my scripted movement.
The approach that I finally settled on, to handle both CharacterController and issues with OnTriggerExit, is to have a separate object that moves along with the character on a separate layer. It has a non-Kinematic Rigidbody and trigger collider, is moved with MovePosition, and forwards any triggers to my character logic. I call it a proxy. Since it’s a separate object, I can count on it to have reliable OnTriggerExit even when my character switches parents (such as riding vehicles) inside various zones in the world. The proxy triggers against special objects like bouncy platforms too, though the bouncy platform now needs to know how to bounce the actual character and not the proxy.
That said, I switched to a fully kinematic character controller and dumped the braindead quasi-collider that is CharacterController. I still use the physical proxy though, as the limitations of OnTriggerExit still exist.