Reseason about the fact that OnCollisionEnter event was not triggered when a GameObject touched the other GameObject.

Reseason about  the fact that  OnCollisionEnter event was not triggered when a GameObject touched the other GameObject.

Q:I stuck on a problem. I  try to develop a new project with Unity. Sometimes,  a gameObject  named unitychan did not pass throught the wall which is left to it the first time it touched the wall. But unitychan passed through the wall which is left to it the second time it touched the wall then I saw uniychan dropping. Sometimes, uniychan passed through the wall which is back to it the first time it touched the wall. I take a look at the the setting of the GameObject in inspector and I ensured that two components(BoxCollider) of two GameObject were attatched.
I stuck it on the similar problem with the third time I looked at it for 4 days.
I finally solved it on third time (at 2021/08/05 p.m. 3:xx).
What happened?

P.S.
PlayerControl.cs script was attached on unitychan GameObject.
The wall was tagged with "Wall_Tag".
The thickness of the wall is 0.5 unit.

Here is my orignal code:
//PlayerControl.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerControl : MonoBehaviour
{
    [Header("Rigidbody JumpSpeed")]
    public float JumpSpeed = 0.8f;

    [Header("Rigidbody Velocity")]
    public Vector3 Velocity;

    [Header("BoxCollider")]
    public BoxCollider boxCollider;

    [Header("message1")]
    public string message1;
    [Header("message2")]
    public string message2;
    [Header("TouchCount")]
    public int TouchCount=0;
    [Header("isTouched")]
    public bool isTouched = false;
    [Header("Movement")]
    public float Movement=0.2f;
    [Header("vector position")]
    public Vector3 vec3=new Vector3(0,0,0);
    // Start is called before the first frame update
    void Start()
    {
        message1 = "1";
        message2 = "2";
        boxCollider = this.GetComponent<BoxCollider>();
        Velocity = GetComponent<Rigidbody>().velocity;
        Debug.Log("boxCollider: name=" + boxCollider.name + " , position=" + boxCollider.center + " , size=" + boxCollider.size);

        //Debug.Log("Start!");
        Debug.Log("gameObject: name=" + gameObject.name);
    }

    // Update is called once per frame
    void FixedUpdate()
    {
        Debug.Log("FixedUpdate!");
        vec3 = new Vector3(0, 0, 0);
        if (Input.GetKeyDown(KeyCode.UpArrow) == true)
        {
            string s = "UpArrow key was pressed down.";
            message1=s;
            Debug.Log(s);
            vec3=new Vector3(0, 0, 1);
        }
        else if (Input.GetKeyDown(KeyCode.DownArrow) == true)
        {
            string s = "DownArrow key was pressed down.";
            message1 = s;
            Debug.Log(s);
            vec3= new Vector3(0, 0, -1);
        }
        else if (Input.GetKeyDown(KeyCode.RightArrow) == true)
        {
            string s = "RightArrow key was pressed down.";
            message1 = s;
            Debug.Log(s);
            vec3=new Vector3(1, 0, 0);
        } 
        else if (Input.GetKeyDown(KeyCode.LeftArrow) == true)
        {
            string s = "Left key was pressed down.";
            message1 = s;
            Debug.Log(s);
            vec3=new Vector3(-1, 0, 0);
        }
        else if(Input.GetKeyDown(KeyCode.Space)==true)
        {
            string s = "Space key was pressed down.";
            message1 = s;
            Debug.Log(s);
            //gameObject.transform.position += new Vector3(-1, 0, 0);
            
            GetComponent<Rigidbody>().velocity += new Vector3(0, 5* Movement, 0);
            Velocity = GetComponent<Rigidbody>().velocity;
            GetComponent<Rigidbody>().AddForce(Vector3.up * JumpSpeed);
            
        }
       if(isTouched==false)
        {
            gameObject.transform.localPosition += vec3;
        }
        gameObject.transform.rotation = new Quaternion(0f,gameObject.transform.rotation.y,0f,0f);
        //boxCollider.center = gameObject.transform.position;
        Debug.Log("boxCollider: name=" + boxCollider.name + " , position=" + boxCollider.center + " , size=" + boxCollider.size);
        
    }
    //override
    private void OnCollisionEnter(Collision collision)
    {
       
        message2 = collision.gameObject.tag+" ";
        if(collision.gameObject.tag=="Ground_Tag")
        {
            isTouched = false;
            string s = "Touch the Ground! OnCollisionEnter event was triggered!"+TouchCount;
            message2 += s;
            Debug.Log(s);
        }
        if (collision.gameObject.tag=="Wall_Tag")
        {
                
            TouchCount += 1;
            string s = "Touch the Wall! OnCollisionEnter event was triggered!"+TouchCount;
            message2 += s;
            Debug.Log(s);
        }
        else
        {
            isTouched = false;
        }
    }
}

A:
I made a common mistake.
I changed my code and solve the probelm.
Here is my new code:
//PlayerControl.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerControl : MonoBehaviour
{
    [Header("Rigidbody JumpSpeed")]
    public float JumpSpeed = 0.8f;

    [Header("Rigidbody Velocity")]
    public Vector3 Velocity;

    [Header("BoxCollider")]
    public BoxCollider boxCollider;

    [Header("message1")]
    public string message1;
    [Header("message2")]
    public string message2;
    [Header("TouchCount")]
    public int TouchCount=0;
    [Header("isTouched")]
    public bool isTouched = false;
    [Header("Movement")]
    public float Movement=0.2f;
    [Header("vector position")]
    public Vector3 vec3=new Vector3(0,0,0);
    // Start is called before the first frame update
    void Start()
    {
        message1 = "1";
        message2 = "2";
        boxCollider = this.GetComponent<BoxCollider>();
        Velocity = GetComponent<Rigidbody>().velocity;
        Debug.Log("boxCollider: name=" + boxCollider.name + " , position=" + boxCollider.center + " , size=" + boxCollider.size);

        //Debug.Log("Start!");
        Debug.Log("gameObject: name=" + gameObject.name);
    }

    // Update is called once per frame
    void FixedUpdate()
    {
        Debug.Log("FixedUpdate!");
        vec3 = new Vector3(0, 0, 0);
        if (Input.GetKeyDown(KeyCode.UpArrow) == true)
        {
            string s = "UpArrow key was pressed down.";
            message1=s;
            Debug.Log(s);
            vec3=new Vector3(0, 0, 1* Movement);
        }
        else if (Input.GetKeyDown(KeyCode.DownArrow) == true)
        {
            string s = "DownArrow key was pressed down.";
            message1 = s;
            Debug.Log(s);
            vec3= new Vector3(0, 0, -1* Movement);
        }
        else if (Input.GetKeyDown(KeyCode.RightArrow) == true)
        {
            string s = "RightArrow key was pressed down.";
            message1 = s;
            Debug.Log(s);
            vec3=new Vector3(Movement, 0, 0);
        } 
        else if (Input.GetKeyDown(KeyCode.LeftArrow) == true)
        {
            string s = "Left key was pressed down.";
            message1 = s;
            Debug.Log(s);
            vec3=new Vector3(-1* Movement, 0, 0);
        }
        else if(Input.GetKeyDown(KeyCode.Space)==true)
        {
            string s = "Space key was pressed down.";
            message1 = s;
            Debug.Log(s);
            //gameObject.transform.position += new Vector3(-1, 0, 0);
            
            GetComponent<Rigidbody>().velocity += new Vector3(0, 5* Movement, 0);
            Velocity = GetComponent<Rigidbody>().velocity;
            GetComponent<Rigidbody>().AddForce(Vector3.up * JumpSpeed);
            
        }
       if(isTouched==false)
        {
            gameObject.transform.localPosition += vec3;
        }
        gameObject.transform.rotation = new Quaternion(0f,gameObject.transform.rotation.y,0f,0f);
        //boxCollider.center = gameObject.transform.position;
        Debug.Log("boxCollider: name=" + boxCollider.name + " , position=" + boxCollider.center + " , size=" + boxCollider.size);
        
    }
    //override
    private void OnCollisionEnter(Collision collision)
    {
       
        message2 = collision.gameObject.tag+" ";
        if(collision.gameObject.tag=="Ground_Tag")
        {
            isTouched = false;
            string s = "Touch the Ground! OnCollisionEnter event was triggered!"+TouchCount;
            message2 += s;
            Debug.Log(s);
        }
        if (collision.gameObject.tag=="Wall_Tag")
        {
                
            TouchCount += 1;
            string s = "Touch the Wall! OnCollisionEnter event was triggered!"+TouchCount;
            message2 += s;
            Debug.Log(s);
        }
        else.
        {
            isTouched = false;
        }
    }
}
I just change my Movement from 1 to 0.2f(=1*Movement) unit.
I suspect that when unitychan touched the wall. the unitychan was moved first then OnCollisionEnter event was triggered after that. 
So, if I set Movement=1 unit. I will see the unitychan  pass through the wall and OnCollisionEnter event was finnally triggered.
When I set  Movement=0.2f unit. I will not see the unitychan  pass through the wall because the thickness of wall is 0.5 unit and the unitychan just move 0.2 unit.

In general, when a BoxCollider of the GameObject touched the other BoxCollider of the GameObject.
OnCollisionEnter event will be triggered. ... .But, it was usually triggered after the Update() or FixedUpdate() was invoked.

I suggest that when a GameObject pass through other GamObject.
(1)Check BoxCollider component of two GameObject were all attached. When either one of BoxCollider component of  GameObject was not attatched to the GameObject, OnCollisionEnter will not be triggered.
(2)Check the Position of BoxCollider.
(3)Check the Movement or Velocity of GameObject (if there exists).
I hope that we will not make the same mistake.
ByeBye.

Comments

Popular posts from this blog

GameObject.SetActive() v.s. GameObject.active

output message to Unity Console - Debug.Log() v.s. Debug.LogWarning() v.s. Debug.LogError() v.s. print()