Reputation: 2220
I have came across similar problem which few people already posted on the forum. I checked the exisiting posts but still not couldn't rectify the issue. I have cube in my program which hits the floor when program starts. However, I found that onCollisionEnter is not being called when cube hits the floor. Rigidbody is attached to the cube. Could anyone guide me where am I making mistake?
Code of cube is:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class cube : MonoBehaviour
{
public float speed = 3.5f;
public float jumpingforce = 10f;
private bool canjump = false;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if(Input.GetKey("right"))
{
transform.position += Vector3.right * speed * Time.deltaTime;
}
if(Input.GetKey("left"))
{
transform.position += Vector3.left * speed * Time.deltaTime;
}
if(Input.GetKeyDown("space"))
{
GetComponent<Rigidbody>().AddForce(0,jumpingforce,0);
}
}
void onCollisionEnter(Collision collision)
{
Debug.Log("checking collision....");
}
}
Upvotes: 0
Views: 88
Reputation: 90833
First of all OnCollisionEnter
needs to start (as btw any method and class name should in c#) with a capital O
.. otherwise Unity will not recognize it and never call it. Unity calls these methods (like also Awake
, Start
, Update
) as "Messages". If they do not exactly match the name they are never found and never called.
Some more things:
Do not call GetComponent
repeatedly. It is quite expensive! Rather store the reference once and re-use it.
Then whenever a Rigidbody is involved you should not update it's transformations using the Transform
component! This breaks the Physics! Rather use Rigidbody.MovePosition
within FixedUpdate
Small Sidenote: Remove any empty Unity message method like Start
, Awake
, Update
. Even if they are empty they are called by Unity as message only causing unnecessary overhead.
So you should change your code to something like
public class cube : MonoBehaviour
{
public float speed = 3.5f;
public float jumpingforce = 10f;
private bool canjump = false;
// you can also already reference this via the Inspector
// then it skips the GetComponnet call
[SerializeField] privte Rigidbody rigidbody;
private void Awake()
{
if(!rigidbody) rigidbody = GetComponent<Rigidbody>()
}
private void FixedUpdate()
{
// Getting this input in FixedUpdate is ok since it is a continues call
if(Input.GetKey("right"))
{
rigidbdy.MovePosition(rigidbody.position + Vector3.right * speed * Time.deltaTime);
}
if(Input.GetKey("left"))
{
rigidbdy.MovePosition(rigidbody.position + Vector3.left * speed * Time.deltaTime);
}
}
private void Update()
{
// this one-time input event has to be checked in Update / frame-based
// since it is true only for one frame and FixedUpdate might not be called during that frame
if(Input.GetKeyDown("space"))
{
// also it's ok calling this in Update since it is a one-time event
// and unlikely to happen twice until FixedUpdate is called again
rigidbody.AddForce(0,jumpingforce,0);
}
}
private void OnCollisionEnter(Collision collision)
{
Debug.Log("checking collision....");
}
}
Upvotes: 3