How to take Two colliders as One ?

Hi,

I have two 2D sprite objects. I put them together and put in an EmptyGameObject so i can use them as one Player object.

Empty gameobject has rigidbody2D and sprites has “Polygon Collider 2D”. I move Player by Rigidbody.velocity in FixedUpdate().

My problem is; when player collides Enemy, it calls function twice by OnCollisionEnter2D().

What i want is; count them as one collider to prevent this bug or anything. It breaks my game style.

Can anyone help me to get over this problem ? Thanks…

Add a bool after it collides with an enemy.

private bool hasCollided = false;
void OnCollisionEnter2D(Collision2D col){

        if(col is enemy){
            if(hasCollided == false){
                // do stuff;
                hasCollided = true;
            }
        }
 
}

Change ‘col is enemy’ to however you idenify an enemy, such as col.tag == “Enemy”

1 Like

I had a similar problem just last week, only in 3D, I used a time stamp and check if time since last hit is greater than x, if it’s not just return.

It’s like when Enemy throws a granade near Player, it call function for each collider that Player has. Then Player will die faster.

Adding a bool into OnCollisionEnter doesn’t work as it will call it twice.

It also won’t work cause they almost collide at same time.

Isn’t there any else way to count them as one ?

Use the timestamp i suggested, if two colliders from the same body get hit in approximatly the same time they count as one, you can modify the thereshold ro suite your use case

1 Like

Hi @SparrowsNest , i don’t know how to use it. Can you exemplify or reference any sources about using it ? Thanks

SparrowsNest’s method should work perfectly well. Here is another solution:

using UnityEngine;

public class MultiColliderCollisionTest : MonoBehaviour
{
    private void OnCollisionEnter2D(Collision2D collision)
    {
        bool isFirstCollider = GetComponents<Collider2D>()[0] == collision.collider;
        if(!isFirstCollider)
        {
            Debug.Log("Collision ignored because was not the first collider.");
            return;
        }

        Debug.Log("Collision detected");

        // react to collision
    }
}
2 Likes
float lastHit;

void OnTriggerEnter(Collider col) {

            if (Time.time - lastHit < .1f)
                return;
            lastHit = Time.time;
            //do other stuff
}

you can change the .1 to what ever the difference you want, have it hardcoded like here, or what ever kind of variable you want.

This was placed on a physical weapon that called a damage function on the collider it hit, should also work from the other side.

one problem with this is if you collide with two different things at the same time only one will count, so maybe a an extra check to see if it’s from the same body will be needed, but I havn’t found a problem with not taking it into account in my use case.

1 Like

Thanks guys for help. I discovered CompositeCollider2D which merges other Colliders together when their Collider2D.usedByComposite is set to true.

I think it does what i really want and need to do. When you add this component to parent GameObject, it will combine all colliders from children GameObjects. So it will be One collider as i understand. I found a video describes how to use it. Thanks :slight_smile:

1 Like

I remember stumbling upon this some time ago, must have slipped my mind…
I wish there was a 3D equivalent for this, that’s probably why I forgot it existed.

1 Like

Adding a bool definitely does work FYI. It gets called the first time and passes through the bool. On the second collision it doesn’t get past the bool. It doesn’t happen at the same time, one must be called before the other.

1 Like

Adding a bool works pretty much like my solution only you have to manually set it back somehow.

I prefer the timestamp because it’s set & forget.

I also had completely forgotten that this existed for 2D colliders. Thanks for sharing! :slight_smile: