How do I print a statement ONLY when two specific colliders collide?

In this lecture, one thing which was happening was that when the player was going through the finish line, the finish line was being triggered twice because there are two colliders on the player (capsule collider on the board and a circle collider on the face). I want to figure out how to fix this such that the finish line is triggered ONLY when the snow board’s capsule collider interacts with the box collider of the finish line.

I wrote this code thinking it might work (it hasn’t) and I’m very confused.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FinishLine : MonoBehaviour
{
    void OnTriggerEnter2D(Collider2D other) 
    {      
        CapsuleCollider2D ABC = other.GetComponent<CapsuleCollider2D>();

        if (this.GetComponent<Collider2D>().IsTouching(ABC))
        {
            Debug.Log("ADASDASDASDASD");
        }
}

Firstly, this script is on the Finish Line game object. My understanding (or lack of) of what I have tried to do here is that the “other” parameter is the game object that’s colliding with the finish line (i.e. The Player). So, I created a variable of Type CapsuleCollider2D since that’s the collider I want to detect. I then used the “IsTouching” method to check if ABC was colliding with the collider of the Finish Line, and if it was, then print that gibberish.

But, the result that I’m getting out of it is this:

  1. The error arises when the box with a 2d box collider triggers the finish line. (I have no idea why).
  2. The gibberish is still being printed when the circle collider on the player’s head triggers the finish line.

Any advice will be helpful if I’m going wrong in my understanding or logic, and sorry for the long question.

Thank you!

Hi MoonLearns,

You are on the right track. Theoretically, your solution should be working unless the other game object does not have a CapsuleCollider2D attached.

IsTouching probably does not check if ABC is null or throws an error message in that case. I would suggest to add an if-statement, e.g. if (ABC == null) { return; }, right after the line with GetComponent. This will make the OnTriggerEnter2D method terminate immediately without executing the rest of the code.

Regarding the “gibberish”, isn’t this what was supposed to get logged into your console when a CapsuleCollider2D was found? Or did you expect something else to happen?

If you know the collider that you want to check, you could make ABC an instance variable with the [SerializeField] attribute. To that variable, you manually assign the “correct” collider component.


If the problem is that the OnTriggerEnter2D method in the FinishLine object gets triggered multiple times, you could try to disable the FinishLine object when the method was called the first time. If that didn’t work, you could work with a new bool variable, e.g. wasTriggered. Maybe that’s easier than checking for a specific collider.


See also:

1 Like

Hello Nina!

THANK YOU SO MUCH for taking out the time to answer my question :sunflower:

1. Adding a return statement does make sense. I will try it right now to see if it works, but it should.

UPDATE 1: It does work.

    //METHOD 1: Finish Line is only triggered when an object has a
    //          capsule collider
    void OnTriggerEnter2D(Colliedr2D other) 
    {  

         CapsuleCollider2D objWithCapCollider = other.GetComponent<CapsuleCollider2D>();
        
        // An if statement to return null in case there is a game object
        // that does not have a capsule collider. If not added, unity
        // will return an error.
        if (objWithCapCollider == null) 
        { 
            return; 
        }

        else if (this.GetComponent<Collider2D>().IsTouching(objWithCapCollider))
        {
            Debug.Log("Triggers when a capsule collider collides with Finish Line");
        } 
    }

2. Regarding the “gibberish” - what I mean’t to say was that what I was logging into the console is the gibberish I wrote. I was referring to the string I was logging as “gibeberish and a jumbled set of letters” and not the output as gibberish (sorry, I should use better variables/log statements).

3. Ooo using serialize field. That is an interesting idea that I shall play around with too right now.

UPDATE 2: I played around with it and again, this was very useful too. This essentially same purpose as using tags. But instead of tags, it just searches for the collider of the gameobject that you manually assign in unity.

    //METHOD 2: Creating objWithCapCollider as a serialze field so that
    //          the trigger only happens when objWithCapsuleCollider
    //          collides with the Finish Line.

    [SerializeField] CapsuleCollider2D objWithCapsuleCollider;
    void OnTriggerEnter2D(Collider2D other) 
    {
        if (this.GetComponent<Collider2D>().IsTouching(objWithCapsuleCollider))
        {
            print("Only printing when the Player collides with the Finish Line!");
        }
    } 

**4. That is a very simple solution to use a bool that I did not think about xD

UPDATE 3: Yup, again, works! basically, the bool is true for the first time the player triggers the finish line, but afterwards it’s false so the statement is not logged.

    //METHOD 3: Using a boolean value to avoid logging when the Finish
    //          Line is triggered multiple times.

    bool wasTrigger = true;
    void OnTriggerEnter2D(Collider2D other) 
    {
        if (other.tag == "Player" && wasTrigger)
        {
            Debug.Log("Player has crossed the finishing line!");
            wasTrigger = false;
        }
    }

5. Nor did I think about disabling the game object itself. Trying this out too.

UPDATE 4: So disabling the game object does not work because it disables every child component (including the renderer) so the finish line vanishes. However, I found out that you can also just disable the collider on a gameobject so I disabled the collider on the FInish Line and that does work. So this means that the Finish Line only works when the Player crosses the Finish Line for the first time.

    //METHOD4: Deactiving the collider on the Finish Line GameObject 
    //          when the Player first collides with the Finish Line

    void OnTriggerEnter2D(Collider2D other) 
    {
        if (other.tag == "Player")
        {
            Debug.Log("Player has crossed the Finish Line!");
            this.GetComponent<Collider2D>().enabled = false;
        }
    }

Personally I preferred the Update 4 method, I feel like it’s the cleanest of them all! And sorry if codes are annoying, I thought I might add these in case other people stumble upon this thread with similar thought processes like I had.

1 Like

That’s what I understood. I was just too lazy to type “ADASDASDASDASDASD” (I’m not going to spell-check this), so I simply reused the word you used yourself. :wink:

That was a misunderstanding. By FinishLine object, I was referring to the C# object, not to some game object named FinishLine. Like this: this.enabled = false;. However, I like your idea better. Disabling the Collider2D object makes sense. :slight_smile:

And sorry if codes are annoying, I thought I might add these in case other people stumble upon this thread with similar thought processes like I had.

I found your approaches and results interesting. Thanks a lot for sharing them.

By the way, since Update 4 works with tags, one thing: When comparing tags, use the more performant CompareTag method.

And keep up the good work! :slight_smile:

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms