- Home /
OnCollisionEnter not working with CharacterController
So I have this script on 2 objects
void OnCollisionEnter(Collision collision)
{
Debug.Log(gameObject.name + " OnCollisionEnter Entered");
}
Object 1 is a sphere with a sphere collider, rigidbody and this script. I put it over a plane with just a box collider. Run the game, the sphere falls on the plane and the log appears. Great.
Object 2 is a character model with a rigidbody set to kinematic, character controller, this script, and another script that calls Move() so the character will fall down onto the plane. When the character falls down to hit the plane, nothing is logged. If I use OnControllerColliderHit, the log appears, but it's being logged every frame. I also tried adding another collider to the model (not a trigger), but i still don't get the log. Is the issue that Move() won't allow OnCollisionEnter to be called? Is there a better way to do this?
Have you had a look at https://answers.unity.com/questions/723010/how-to-make-kinematic-rigidbody-react-to-some-coll.html ?
Also, if you have a look at https://docs.unity3d.com/ScriptReference/Rigidbody.OnCollisionEnter.html it states:
Notes: Collision events are only sent if one of the colliders also has a non-kinematic rigidbody attached.
$$anonymous$$eaning that you either have to adjust your Rigidbody or find a different way of getting it to work, if you absolutely must have it kinematic ^^"
Answer by mbro514 · Jul 04, 2020 at 10:20 PM
Character Controllers don't call OnCollisionEnter or OnCollisionStay when they collide with other GameObjects. They only call OnControllerColliderHit(). Unfortunately, OnControllerColliderHit() is called every single frame that the Character Controller is touching the other object, and there is no similar method for only the first frame that a collision occurs. You would have to code this function yourself.
Hey I've been having this problem. How could you code this yourself? Could you have a cube or cylinder or something at the same position with oncollisionenter? Thanks
Hey @harranj. I'm pretty sure it would not be a good idea to use a cube or a cylinder with a kinematic rigidbody, as it would only be able to send out collision callbacks if it hit a dynamic rigidbody, which is probably not the behaviour you're looking for.
How I would code my earlier answer would be (I've never tried it, but it should hopefully work.)
bool isTouchingGround;
void OnControllerColliderHit(ControllerColliderHit hit)
{
if (hit.gameObject.layer == Layer$$anonymous$$ask.NameToLayer("Ground"))
{
if (isTouchingGround)
{
// Put in the code that you would have put into OnCollisionEnter
}
else
{
// Put in the code that you would have put into OnCollisionEnter
isTouchingGround = true;
}
}
}
void FixedUpdate() { // To replicate OnCollisionExit, put some code in here (probably using a Physics Query) to tell if you are touching the ground, and if you're not... if (isTouchingGround){ // Put in the code that you would have put into OnCollisionExit isTouchingGround = false; } }
You could use code similar to this for any other collision callbacks that you need.
Just a side note, collisions between kinematic bodies may be enabled in the Physics section of the Project Settings: Set Contact Pairs $$anonymous$$ode to Enable All Contact Pairs.
Worked for me, this is the only solution I think. Here is part of my script. I used collision with tags.
void OnControllerColliderHit(ControllerColliderHit hit)
{
if (hit.gameObject.tag == ("Wall"))
{
Debug.Log("work");
}
}
Your answer
Follow this Question
Related Questions
Is there a rigidbody character controller 3rd person that can handel stairs (steps)? 1 Answer
Can't use Rigidbody or Character Controller 0 Answers
Physic based golf game - ball bouncing off the connection of colliders on flat surface 2 Answers
How can I make two Character Controllers Collide 2 Answers
Alternatives to CharacterController.Move to drive a car 1 Answer