- Home /
Can I enable/disable a collider so it will/won't detect mouse clicks?
I have some 'billboard' planes I use as UI objects in my scene. They have mesh colliders on them so I can detect when user mouse-clicks on them. I need to hide/show these things. The problem is, even hidden, the colliders are intercepting mouse-clicks, such that an invisible one in front of a visible one will 'hide' the visible one, so the visible one does not detect mouse clicks (I hope that made sense).
Is there a way to 'disable' a mesh collider such that it won't intercept the click? It has no 'enabled' field. Note that the renderer is disabled, that alone was not enough to disable the collider.
Or is there a better way to do mouse-clicks?
BTW: I tried setting the collider's 'isTrigger' but that didn't seem to help in this case.
Answer by DaveA · Aug 20, 2010 at 11:16 PM
Well, this doesn't solve the actual problem (disabling collider/mouse), but it's actually a cool work-around which works very well for me, so I'll share it: When I need to disable (hide) my collider, I use the Update function to reduce the scale (over time) to zero, and when I show it, return scale to 1. This shrinks the colliders so they are out of the way, and has the added bonus of looking cool while it's doing it.
Seems it's an oversight, wish they'd fix it, but the above seems to work. Could also move it out of sight or otherwise just hide things.
Yeah, I agree. This is a really good work around. Not much of a solution though. Unity needs to fix this.
just stumbled into a case where i ended up searching for a bug that was due to collider.enabled = true
not working... but to use your method directly, you could just set the collider scale to Vector3.zero
rather than having to use Update()?
Thank you for this workaround, that's a really great way to disable/enable colliders since collider.enable(true/false) still allows collisions and does not help, as well as deactivating/activating a gameobject.
Answer by Markq · Dec 08, 2010 at 08:53 AM
What you can do is to put the object on another layer by setting its layer property and then excluding that layer when raycasting. You perform the hit test as follows (the excluded objects are on layer 8 in this example):
RaycastHit hit;
if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition),
out hit, Mathf.Infinity, ~(1 << 8))) {
print("It's a hit!");
}
See also: Layers in Unity documentation
If you use the built-in IgnoreRaycast layer, you don't even have to do anything else differently. Also works with On$$anonymous$$ouseDown etc. (which use raycasting behind the scenes). If you use a custom layer(s), you may find it simpler to use the Layer$$anonymous$$ask type ins$$anonymous$$d of bitshifting.
This sounds pretty good. $$anonymous$$y objects are already in a special layer (which I toggle to hide/show all these objects), so I should have thought of this myself earlier. I'd have to make an additional layer then. Eg: I have a 'data' layer which displays these 'data objects', I might have to add a 'hidden data layer' which would hold them while 'disabled'
Answer by Bunny83 · Jan 15, 2011 at 03:39 AM
Like Markq mentioned the best way is to use layers. If you just want to enable / disable the OnMouseXXX events of a certain GO use this:
edit
// disable Raycasts gameObject.layer = 2;
// enable Raycasts (set to default layer) gameObject.layer = 0;
Layer 2 (start counting by 0) is the IgnoreRaycasts layer if your GO is on that layer it will be ignored by unity.
I thumbed up for posting info on which layer is by default the 'ignore raycast layer' - but there's a mistake in the answer, if you want to disable you actually want:
gameObject.layer |= 1<<1;
and similar change with enable raycasts. :) (1 << 1 : sets it to layer 2, the default raycast ignore layer, not sure why layer 4 is being used here)
Yes, you're right, but it's not 1<<1 ;) $$anonymous$$y mistake was that the layer property on a gameobject holds the layer index and not a layer mask
The ignore-raycast-layer is layer 2 (but you start counting at 0 so it's the 3rd layer). The decimal value of the constant Physics.kIgnoreRaycastLayer is 4 == 1<<2, however we need the layer index ins$$anonymous$$d of a layer mask. I will edit my answer ;)
Layer Name Index Layer$$anonymous$$askValue
----------------------------------------------
Layer0 Default 0 1 == 1 << 0 == 00000001
Layer1 TransparentFX 1 2 == 1 << 1 == 00000010
Layer2 IgnoreRaycast 2 4 == 1 << 2 == 00000100
Layer3 3 8 == 1 << 3 == 00001000
Layer4 Water 4 16 == 1 << 4 == 00010000
ic. layermask value of 2 (aka, 1<<1) incidentally still works.
:D Yes it does work, but doesn't make any sense since the layer property is not a layermask. You just need the value 2 (the index) and not a bitmask representation.
Answer by joedrigon · Aug 19, 2010 at 04:04 AM
Yea, I don't think you can enable/disable colliders like some of the game objects other components. I could be wrong...but... you could "destroy" the collider when you don't want it used then "addcomponent" it when you want it...
I'm not sure if this is the best way, I'm still very new to Unity...
I think the overhead of create/destroy, and the iffy-ness of garbage collection precludes me using this, but thanks.
Answer by SpiderJones · Mar 27, 2021 at 01:23 AM
Hi, you can do this...
[SerializeField] private LayerMask inputLayerMask;
private void Start()
{
Camera.main.eventMask = inputLayerMask;
}
Then in the game object's inspector set what layer mask, or masks, you want to receive mouse input.