This is my idea of fun
Making video games...
The problem
I’ve seen a lot of people asking for help on forums on how to detect right clicks in a Unity3D game. It’s indeed not that easy as no native method is really made for it.
We have the good old OnMouseDown method that can be used on any game object having a collider component but it only handles the left clicks
Web games warning: first disable context menu!
By default, when you build your game for web player, right clicks on the game frame will open the context menu.
You can easily disable this behavior by setting the disableContextMenu parameter to true in your web page’s javascript code.
See web player’s behavior documentation for more details.
The easy way
The solution
As mentionned by Eric5h5 in his answer to my unity3D forum thread, there’s a very easy way to detect right clicks on a game objects in Unity3D.
The principles is to combine OnMouseOver and Input.GetMouseButtonDown methods.
The first one is triggered when the mouse cursor is dragged over current game object. Every left/right/middle mouse button click on our game object will occur while the mouse cursor is over it. So this is our first filter.
The second one will return true if one of the mouse button as been pressed during the frame it’s being called. The first (integer) parameter of this method specifies which mouse button you want to track (0 for left button, 1 for right button, 2 for the middle button). This is how we know if a right click as occur on our game object.
The code
function OnMouseOver()
{
if (Input.GetMouseButtonDown(1))
{
// Right button clicked on this object
}
}
Pros and cons
The advantage of this method is that it’s easy to implement and it also works on GUI texts and textures.
The counterpart is that the code will have to be executed on every game object you want to listen for right clicks.
Simply put, it is the best solution for most of the cases but you could need to optimize your code and want to scan clicks only once per frame. The next chapter presents another solution which is recommenced for scenes with a lot of game objects tracking right clicks.
The complicated/optimized way
Detect mouse button clicks
The right way to detect right (and middle) clicks is to use the Input class and especially its GetMouseButtonDown method.
As the Unity3D script reference documentation states it, the first (integer) parameter of this method specifies the mouse button you want to track (0 for left button, 1 for right button, 2 for the middle button). All right, so now we know when the left/right/middle mouse button is clicked! … but wait, what has been clicked ?
Find the targeted game object
Our new problem is to know which game object was targeted during the click we just detected. Indeed, unlike the OnMouseDown method, the GetMouseButtonDown is a method of the Input class, which isn’t “linked” to any game object in particular.
The way we’ll solve this problem is pretty simple: draw a line from camera to mouse position and continue drawing until our pen hits something (our target). There’s a very useful tool present in Unity3D which will help us to perform it: ray casting (simply put, “ray” = “line” and “casting” = “drawing”
), and more precisely the Physics.RayCast method.
But first we have to build this ray. We know current mouse position thanks to the Input.MousePosition vector. We also know where our main camera is placed as we can access its transform component.
We could build it using those 2 informations but there’s an easier way to do it: the Camera.ScreenToPointRay method. Simply set the mouse position as first parameter of this method and magic! you have your ray.
Final step is to find which game object has been hit by the ray we just casted. Once again it’s pretty simple as the Physics.RayCast method takes a pointer/modifiable parameter name “hitinfo”. This parameter will be filled with a RaycastHit object, containing the transform of the targeted game object. Add a “.gameObject” to the result and you get your target!
[Advanced] Wait not this one, the one behind it
Maybe you just want to listen for clicks on your main character and don’t want to trigger anything when clicking on the robot passing by between your camera and your character. Or you still want your click to be detected when he moved behind a tree. You can do it by using Unity3D’s layer filtering feature.
By chance, the Physics.RayCast method handles it perfectly
Just set the correct layer mask has fourth parameter and you’re done: ray will only hit game objects of the layer(s) you specified.
ClickDetector.cs
Here’s the script I use on several of my Unity3D projects for mouse click detection. It can be reused on any project as it doesn’t rely on any other specific class.
It’s based on the SendMessage method usage and is fully customizable (see exposed parameters in Unity3D editor).
Simply drag it to only one game object in your scene and define the OnLeft/Right/Middle methods on the game objects you want to handle clicks.
Download this script or copy it from following source:
using UnityEngine;
using System.Collections;
public class ClickDetector : MonoBehaviour
{
public bool HandleLeftClick = true;
public bool HandleRightClick = true;
public bool HandleMiddleClick = false;
public string OnLeftClickMethodName = "OnLeftClick";
public string OnRightClickMethodName = "OnRightClick";
public string OnMiddleClickMethodName = "OnMiddleClick";
public LayerMask layerMask;
void Update()
{
GameObject clickedGmObj = null;
bool clickedGmObjAcquired = false;
// Left click
if (HandleLeftClick && Input.GetMouseButtonDown(0))
{
/*if (!clickedGmObjAcquired)
{*/
clickedGmObj = GetClickedGameObject();
clickedGmObjAcquired = true;
/*}*/
if (clickedGmObj != null)
clickedGmObj.SendMessage(OnLeftClickMethodName, null, SendMessageOptions.DontRequireReceiver);
}
// Right click
if (HandleRightClick && Input.GetMouseButtonDown(1))
{
if (!clickedGmObjAcquired)
{
clickedGmObj = GetClickedGameObject();
clickedGmObjAcquired = true;
}
if (clickedGmObj != null)
clickedGmObj.SendMessage(OnRightClickMethodName, null, SendMessageOptions.DontRequireReceiver);
}
// Middle click
if (HandleMiddleClick && Input.GetMouseButtonDown(2))
{
if (!clickedGmObjAcquired)
{
clickedGmObj = GetClickedGameObject();
clickedGmObjAcquired = true;
}
if (clickedGmObj != null)
clickedGmObj.SendMessage(OnMiddleClickMethodName, null, SendMessageOptions.DontRequireReceiver);
}
}
GameObject GetClickedGameObject()
{
// Builds a ray from camera point of view to the mouse position
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
// Casts the ray and get the first game object hit
if (Physics.Raycast(ray, out hit, Mathf.Infinity, layerMask))
return hit.transform.gameObject;
else
return null;
}
}
Demo project
A demo is worth a thousand words so here’s a project showing how to use it all.
Awaiting your comments and feedbacks!
10 Comments »
Leave A Response »













Hi! I am new to Unity3D and I am presently trying to create my first game. This explanation of the Right-Mouse-Button problem and the Demo project has greatly helped me. Just wanted you to know that, and to say a great Thank You!
You’re welcome, glad I could help!
You are a god (not really, but close
). Very helpful and informative for new Unity users
Comment approved! XD
Hello good sir,
Can you explain to a new Unity user a bit more how to use this nice piece of code that you so unselfishly share it with us?
For example: I have created a tile grid and I have tile objects and unit objects on the map (as you may have guessed it’s a turn-based strategy wanna be game). How can I use your ClickDetector?
I have put your script on an empty object in my scene, but what next? Do I have to put any code in my “tile” and “unit” objects? I can understand most of the code, but the variables at the top before the update functions and the SendMessage confuse me.
Thank you for your code and it would be really nice, if you could help me
Just something more to ask. Do you think that your script is a good solution to handle mouse clicks for my project or shall I try to find something different?
If you’re using the right click and don’t want that menu in your face:
File > Build Settings > Player Settings > “Resolution and Presentation” > WebPlayer Template” > “No Context Menu”
I downloaded the ClickDetect.cs code but not having any luck getting it to work. The Raycast() in GetClickedGameObject() is always returning null.
I also have the demo project which works. Is there a camera setting that I am missing?
I copy one of the cubes from the demo scene to my scene. Clicking on the cube works, but still nothing for the objects I have created. In the editor my object is the same as cube. What am I missing?