proper way to detect collisions between two character controllers?

I’ve got a simple game where the player moves around with a CharacterController, chased by monsters with the same. I’d like the player to take damage when touched by the monsters.

The problem is, my OnCollisionEnter (and OnTriggerEnter, for that matter) methods aren’t getting called, even when the player in the center of a monster group hug.

I tried OnControllerColliderHit, and I see that being invoked for the terrain and for other environment objects (with mostly box colliders) that the player bumps into. But, frustratingly, it doesn’t get invoked when the player bumps into other CharacterControllers. Moreover, according to the docs, OnControllerColliderHit only gets called for things the character bumps into during a Move. So it doesn’t seem suitable for this purpose, as you wouldn’t take damage while standing still.

I’ve done a bit of searching, and run into a lot of other people asking similar questions, but no good answers. Often the recommendation is to add an additional collider just for this purpose, but that seems like a hack… what’s the proper way to detect collisions between two CharacterControllers?

Thanks,

  • Joe

Have you tried a raycast?

No… of course there are all sorts of things I could do “manually,” such as having all the monsters check the distance to their target and call a method if it’s under some limit.

But I shouldn’t have to.

Surely there’s some way to use the physics engine, which is already detecting and handling these collisions (to keep things from intersecting each other), to get these collisions in some more automatic manner?

After more experimentation, I can get collisions to work properly if I add a separate CapsuleCollider (or other standard collider class) to my characters. This extra collider must be set with IsTrigger=true, and it must be sized larger than the character controller, so that it sticks out on all sides. Under these conditions, I get proper OnTriggerEntered callbacks when things hit 'em.

My current theory for this is that, even though CharacterController derives from Collider, it isn’t really treated as one by the physics engine — it’s used only to prevent collisions, not to report them. If you want to react to collisions, you need a separate collider for that (and it must be bigger than the CharacterController, or the latter will prevent the former from actually colliding).

Still seems a bit hackish, though… if anybody has a better solution, I’d love to hear it.

Yep, that’s exactly it.

The character controller is faking physics by doing ray/capsule casts to slide along obstacles, step up/down stairs, and reacting when it bumps into objects. But it doesn’t have a collider object that is hooked into the physics engine so adding one manually is the best solution.

The other solution would be to create a custom controller that contains a character controller, do a Physics.CapsuleCastAll each frame, and then send the collision messages manually. But that’s exactly what simply adding a capsule collider to your object is doing anyway so I think simply adding the extra collider is the best and easiest way to go.

It seems hackish, but I think that’s because character controllers’ interactions with physics are generally a huge hack. First-person shooters have conditioned players expect to be able to run at 50km/h, stop on a dime, and have a 3m vertical jump. So you just hack the interaction together to get it to “feel” right–physics be damned.