Juan Francisco Patino
Juan Francisco Patino

Reputation: 83

Unity3D collision detection not working

I'm having difficulty with OnCollisionEnter while making a dodgeball game, so is there any way I can make the player lose lives/points when it's hit with a ball with a specific color?

What I've tried:

The script on the player:

    void Start () {
    livesText = GameObject.FindWithTag("lives").GetComponent<Text>();
    lives = 4;

}

// Update is called once per frame
void Update () {

    livesText.text = "Lives: " + lives;
}

void OnCollisionEnter(Collision bol)
{
     if (bol.gameObject.name == "blueBall")
    {

      lives = lives - 1;

      Debug.Log("Collided");

      }


}

enter image description here

enter image description here

Player prefab: The highlighted portion is the actual physical body of the player:

enter image description here

BREAKDOWN of the player prefab:

PLAYER1:

enter image description here

FPSController:

enter image description here

FirstPersonCharacter:

enter image description here

CAPSULE:

enter image description here

Upvotes: 0

Views: 1094

Answers (1)

Programmer
Programmer

Reputation: 125455

You can do this in two ways depending on if the color is generated during game-play or color that already exist is used.

Method 1:

Create a tag for each color then make sure that each object has it's tag assigned in the Editor. Use CompareTag to compare which color it collided with.

Here is a quick tutorial on how to create tags.

void OnCollisionEnter(Collision bol)
{
    if (bol.gameObject.CompareTag("blueBall"))
    {
        lives = lives - 1;
        Debug.Log("Collided red");
    }
    else if (bol.gameObject.CompareTag("greenBall"))
    {
        lives = lives - 2;
        Debug.Log("Collided green");
    }

    else if (bol.gameObject.CompareTag("blackBall"))
    {
        lives = lives - 3;
        Debug.Log("Collided black");
    }
}

Method 2:

Now, if you are doing something advanced that you have to generate color in run-time, you have to check the threshold of the color. There is a question about this here and I ported the code for Unity.

public double ColourDistance(Color32 c1, Color32 c2)
{
    double rmean = (c1.r + c2.r) / 2;
    int r = c1.r - c2.r;
    int g = c1.g - c2.g;
    int b = c1.b - c2.b;
    double weightR = 2 + rmean / 256;
    double weightG = 4.0;
    double weightB = 2 + (255 - rmean) / 256;
    return System.Math.Sqrt(weightR * r * r + weightG * g * g + weightB * b * b);
}

Then do something like this in the collision callback function:

void OnCollisionEnter(Collision bol)
{
    MeshRenderer ballMesh = bol.gameObject.GetComponent<MeshRenderer>();

    if (ColourDistance((Color32)ballMesh.sharedMaterial.color, (Color32)Color.red) < 300)
    {
        lives = lives - 1;
        Debug.Log("Collided red");
    }
    else if (ColourDistance((Color32)ballMesh.sharedMaterial.color, (Color32)Color.green) < 300)
    {
        lives = lives - 2;
        Debug.Log("Collided green");
    }

    else if (ColourDistance((Color32)ballMesh.sharedMaterial.color, (Color32)Color.black) < 300)
    {
        lives = lives - 3;
        Debug.Log("Collided black");
    }
}

EDIT:

The OnCollisionEnter function is not being called because you are using the First Person Controller.

In this case, you must use the OnControllerColliderHit function.

void OnControllerColliderHit(ControllerColliderHit bol)
{

}

everything in the function remains the-same.

Upvotes: 2

Related Questions