Having more than one collider in a GameObject?

Can we create more than one colliders in a GameObject and then access those colliders as an array or something?

I have one gameobject with a box colliders that i’m using for physics. However, i want a second collider, doubled in size, to be the colliders that my “mouse clicking code” will see. One collider is used for physics, the other one for the mouse to raycast properly.

You can add multiple colliders to the same object, but they have to be different types. e.g., sphere + box = fine, box + box = impossible. Also all colliders will be used for the same purpose; you can’t have one collider be for physics and one not. You can add multiple colliders of the same type using children, but again all of them count as the same collider of the parent (known as compound colliders). In order to have two different colliders act in different ways, you must use two separate gameobjects.

The way I got around this was to use the layers system. If you put the one collider on a gameobject then put the second on a child of the game object you can set the layer on the child to something like IgnoreRaycast which will make it invisible to the physics engine. Which is really useful in certain aspects. Like mmmPies problem, you could use the collider that you put in the IgnoreRaycast layer as range. So you’d make it a sphere in your script you use a collision between that collider and the player to pick up the item. Granted mmmPies found his own solution but when you pickup script relies on colliders this works.

Found an answer to this here. The answer was leveraging the type of the colliders on the gameobject to determine what to do:

void OnCollisionEnter2D(Collision2D collision)
{
    if (collision.collider.GetType() == typeof(BoxCollider2D))
    {
        // do stuff only for the box collider
    }
    else if (collision.collider.GetType() == typeof(CircleCollider2D))
    {
        // do stuff only for the circle collider
    }
}

or using an array index, such as var collider1 = GetComponents<BoxCollider>()[0];

Bumping this because I came up with a simple solution. I wanted to fire an arrow and have it stick in whatever it hit (so it needed a trigger collider to do that) and I gave it box collider so it didn’t fall through the terrain.

Also wanted a 5 meter radius collider so I could either pickup automatically or display an icon to give the choice to pick up the arrow on the floor. Came to this post hoping for a solution to multiple colliders in one gameobject, then I realised I’d seen something similar in the Burgzerg treasure chest tutorial. So I used that:

public bool AlwaysPickup;		// If yes picks up on collision (small item like arrows). If no displays pickup icon.

private Transform _itemTransform;
private GameObject _player;
private float _inRange;
private bool _triggered;
private bool _released;

void Awake()
{
	_itemTransform = transform;
	_player = GameObject.FindGameObjectWithTag("Player");
	_inRange = 5f;
	_triggered = false;
}

void Update()
{
	if(_player == null)			// Probably wasteful. Consider changing the order of the scripts so the Player is available
	{
		_player = GameObject.FindGameObjectWithTag("Player");
	}

	if(Vector3.Distance(_itemTransform.position, _player.transform.position) < _inRange)
	{
		if(!_triggered)
			Trigger ();
	}
	else if (!_released)
		Released();
}

private void Released()
{
	_triggered = false;
	_released = true;

	Debug.Log ("Exited range at: " + Time.time);

	if(!AlwaysPickup)
	{
		Debug.Log ("Remove display pickup icon here");
	}
}

private void Trigger()
{
	_triggered = true;
	_released = false;

	Debug.Log ("Entered range at: " + Time.time);

	if(AlwaysPickup)
	{
		Debug.Log ("I should handle picking up the item here");
	}
	else
	{
		Debug.Log ("Put display icon here");
	}
}

You can attach multiple empty gameObjects with Coliders to your main gameObject,
and attach to them simple script, which triggers Actions, which can be subscribed by parent gameObject.

Each child gameObject with collider will have the same script:

{

    using UnityEngine;
    using System;

    public class Collision2D_Proxy : MonoBehaviour
    {

    public Action<Collision2D> OnCollisionEnter2D_Action;
    public Action<Collision2D> OnCollisionStay2D_Action;
    public Action<Collision2D> OnCollisionExit2D_Action;

    private void OnCollisionEnter2D(Collision2D collision)
    {
        OnCollisionEnter2D_Action?.Invoke(collision);
    }

    private void OnCollisionStay2D(Collision2D collision)
    {
        OnCollisionStay2D_Action?.Invoke(collision);
    }

    private void OnCollisionExit2D(Collision2D collision)
    {
        OnCollisionExit2D_Action?.Invoke(collision);
    }

    // etc ...
}

Parent gameObject needs just to subscribe required events:

public class CharacterBehaviour : MonoBehaviour
{

    private Collision2D_Proxy firstCollider;
    private Collision2D_Proxy secondCollider;


    void Start()
    {
        // subscribe collision events

        firstCollider = transform.Find("FirstChildGameObjectName").GetComponent<Collision2D_Proxy>();
        firstCollider.OnCollisionEnter2D_Action += firstColider_OnCollisionEnter2D;

        secondCollider = transform.Find("SecondChildGameObjectName").GetComponent<Collision2D_Proxy>();
        secondCollider.OnCollisionExit2D_Action += secondColider_OnCollisionExit2D;
    }

    private void firstColider_OnCollisionEnter2D(Collision2D collision)
    {
        print("first collider OnCollisionEnter2D collision" );        
    }

     private void secondColider_OnCollisionExit2D(Collision2D collision)
    {
        print("second collider OnCollisionExit2D collision" );        
}

Either add another collider component to the same object and enable the IsTrigger option in the inspector, Or create an empty game Object and make it a child and add a collider to the empty object and also enable IsTrigger

I’m pretty sure that you can add any type of collider into an object with a collider already on. I put a Box Collider on a Cube to make a falling pit, and Unity didn’t throw me an error. And I’m pretty sure if you write - public ColliderNameHere NameOfArrayHere; - to be able to do an array of colliders, than specify the size and colliders you want in the inspector tab on the object of choice.

I know this is late, but someone might need this. There’s a much easier way! Put the mouse click collider on the parent object and then the smaller collider that interacts with other objects on a child object. Then give the child it it’s own layer (named HitBox). Make the parent object on a separate layer (clickBox). Then under layers on clickBox, disable it for everything and make sure everything is checked for HitBox. This way, the clickBox layer will only interact with the mouse click and HitBox will interact with everything else. Hope this helps =).