Reese Schultz

Coding, gaming and rambling.

Pointing and Clicking with Unity

How to retrieve position and GameObject information through pointing and clicking in Unity.

Last updated on December 19, 2019. Created on November 8, 2019.

Update: I wrote a tutorial for pointing and clicking on entities, as in ECS, if you're interested.

Retrieving position and GameObject information through mouse clicks is simple. To do this, you need a MonoBehaviour with a public Camera field or setter, and an implemented LateUpdate function. The LateUpdate function will use the camera to project the 2D point where you clicked onto the 3D scene. We use LateUpdate because we need a camera to observe stuff that may have occurred during Update. Here's the code:

using UnityEngine;

namespace SomeNamespace
{
    class PointAndClick : MonoBehaviour
    {
        public Camera Cam;

        void LateUpdate()
        {
            if (!Input.GetMouseButtonDown(0) || Cam == null) return;

            RaycastHit hit;
            if (!Physics.Raycast(Cam.ScreenPointToRay(Input.mousePosition), out hit)) return;

            Debug.Log(hit.point);
        }
    }
}

To use this script, add it to an empty GameObject in a scene; drag and drop a camera from the scene onto the script's Cam field.

Note that in said LateUpdate function, we first return if the left mouse button is not being clicked, or if the camera is null, so hopefully you set that Cam field. Then we create a RaycastHit variable appropriately named hit. We call Physics.Raycast, passing a ray to it that is projected from the 2D point on the camera screen to the 3D scene space via Camera.ScreenPointToRay (meaning we don't have to do the matrix math ourselves).

Continuing on, we pass the self-explanatory Input.mousePosition to that function. Note that, for Physics.Raycast, out hit means to write data to the previously defined hit. (Here is the C# reference on out.) Finally, keep in mind that Physics.Raycast returns true if there is a detected hit (or collision with a GameObject), but false if not. We immediately halt execution if there is no hit.

The last part of the script outputs the Vector3 point of hit, just for the sake of example.

But, RayCastHit has a number of other members we might be interested in, probably the most popular properties including:

  • collider: Collider
  • distance: float
  • normal: Vector3
  • rigidbody: Rigidbody
  • transform: Transform

And there are others listed in the official documentation.

collider, rigidbody, and transform are especially useful since they all reference the owning GameObject via gameObject. Yep, that's right, you can retrieve the associated GameObject by calling any of the following:

  • collider.gameObject
  • rigidbody.gameObject
  • transform.gameObject

With all that in mind, now you have all the tools you need to read or manipulate scene data through pointing and clicking.

© Reese Schultz

My code is released under the MIT license.