I’m making a game prototype for a college class. I am trying to make drawers interactable. I’ve created an animation sequence that plays when a left button is clicked. My problem is, I have a bunch of drawers that I want to be interactable when clicked. However, when I left-click all my drawers move. I know I need to use raycast(?) and have box colliders. I’ve got box collider’s on my drawer, but it still isn’t working. I don’t know what the problem is…let alone fix it.
I’ve been using Unity for less than two weeks, so I’m not trying to learn C# completely, just get this prototype working. All the tutorial’s I’ve found are at least 1.5 years old, so I don’t know where else to turn. I don’t even know what information to add to this post, so I guess let me know if I’m missing something? The script is also called ClickTrigger, but is referenced as GDT_GDT_DetectMouseOnGameObjects in the software.
As long as that script is on the same GameObject as the collider, it should work.
Note that as the docs say, you either have to turn off the IsTrigger toggle on your BoxCollider, or find the “Queries Hits Triggers” toggle in the project’s physics settings and make sure it is on.
You need to either use Unity 6.4+ or set “Active Input Handling” to “Both” or “Input Manager” in player settings. The new input System only got support for these events late last year in 1.16.0 and Unity 6.4.
The more compatible approach is to create an Event System (GameObject » UI (Canvas) » Event System) and add the “Physics Raycaster” component to your camera. Then you can implement any of the event interfaces on a script with a collider on the same game object. For a click you want the IPointerClickHandler interface (see the link for an example).
The advantage is that UI elements will properly block clicks, provides more events, more details about the ray / hit and selection / navigation management. The downside is that it’s more complicated to set up.
I originally had a basic OnMouseDown script, but I thought that was causing all of my drawers to move at the same time since they all had the same trigger and there was no distinction? That’s why I tried the new script. I did change “Active Input Handling” to “Both” and I have an Event System. I added the physics raycaster to my player follow camera, which I got by downloading the free first person controller from the asset store. Is that the right camera to add it to, or am I supposed to add it to the main camera?
I basically get lost after I add a physics raycaster. So far, what I understand is each drawer needs a collider box (with “Trigger” unchecked), and a script that tells it to play the animation when the game object clicked. That script should be attached to that same thing that has the box collider. But I have no idea how to write that script since I don’t understand any of the naming conventions, otherwise I’d freestyle it myself. I’ve just removed all of my animation sequences and animator controllers so I can start fresh (because I somehow beefed them all up, so my drawers are randomly placed around the room).
Is there some sort of C# for dummies book I can read to learn the naming conventions or something? I tried looking at the link you provided, but I’m missing so much foundational knowledge it’s not really helping me
OnMouseDown on a MonoBehaviour means “did this specific object get clicked”. So the naming there is a bit misleading, it doesn’t fire on all the script instances when you click, only the ones that have colliders that are under your mouse.
So the general way you’d do this, which is a bit nicer, is to split that job into two:
one script that lives kinda wherever that checks “what did I click on” and sends messages to the drawers when they get clicked
one script on each of the drawers that receives that message and plays the animation.
The very minimal version is just these two scripts:
using UnityEngine;
using UnityEngine.InputSystem;
// ClickHandler.cs
// Place a single instance wherever - like on your camera.
public class ClickHandler : MonoBehaviour {
void Update() {
if (Mouse.current.leftButton.wasPressedThisFrame) {
var mousePosScreen = Mouse.current.position.ReadValue();
var ray = Camera.current.ScreenPointToRay(mousePosScreen);
if (Physics.Raycast(ray, out var hit))
if (hit.collider.TryGetComponent<Drawer>(out var drawer))
drawer.PlayAnimation();
}
}
}
// Drawer.cs
using UnityEngine;
// Place on the Drawers objects
public class Drawer : MonoBehaviour {
public Animator animator; // assign in the Inspector!
public void PlayAnimation() {
animator.SetTrigger("ClickTrigger");
}
}
With this you don’t need the Physics Raycaster component, and you don’t need to fiddle with the active input handling.
Not that the Physics Raycaster idea isn’t a good one long term - it’s a clever way to deal with UI overlapping gameplay. But to just get things working, the two scripts above should get you started.
That’s one of those problems that a lot of us don’t remember the answer to anymore, lol. Maybe I read a book when I was learning C# in 2010? Who knows? I’ll let somebody else try to answer that one
Thank you, thank you, thank you, thank you. You’ve literally saved my life/college class with this. I cannot express how happy and grateful I am right now. It works perfectly!! I was starting to think I’d never get my prototype working, but you saved the day.