Selecting a Target with the Mouse - Unity Game Development Tutorial

In this Unity game development tutorial we're going to look at how we can select a target in the 3D world using the mouse.

You can either watch the video version below or continue reading for written instructions.

We're going to start with the scene we created in our 'Colliding with Obstacles' tutorial. 

We've got a ball and a stack of boxes that all have a Rigidbody component attached so that they react to forces and collisions.

The initial scene with a ball and a stack of boxes

We're going to add the ability to select a target with the mouse and then fire the ball at the selected target when the left mouse button is clicked.

The first thing we're going to do is make the cardboard box change colour when the mouse cursor is over it, so the player knows which box they are targeting.

To do this, we'll go to the Project panel and navigate to Assets->CrowArt PBR Cardboard Box->Prefabs, and we'll select the 'CarboardBox_1' box prefab. 

We'll add a script to the prefab by clicking the 'Add Component' button and searching for the script component. We'll call this script Target.

Creating the Target script

Adding the script to the prefab of the cardboard box will apply it to all of the boxes in our scene.

We'll double click the script to open it in Visual Studio and change it to match to the following.

using UnityEngine;

public class Target : MonoBehaviour
{
    private Renderer renderer;

    void Start()
    {
        renderer = GetComponent<Renderer>();
    }

    private void OnMouseEnter()
    {
	renderer.material.color = Color.red;
    }

    private void OnMouseExit()
    {
        renderer.material.color = Color.white;
    }
}

We are changing the albedo colour of the material when the mouse is over the box in the same way as we did in our 'Changing the Colour of a Material' Tutorial.

To get access to the material, we need to get the Renderer component, so we've created a private field for this. Then we're getting the Renderer component in the Start method and assigning it to the field.

We're then making use of the OnMouseEnter method which will be called when the mouse is over the box. In here, we're accessing the material of the Renderer and setting the colour to red. 

The OnMouseExit will be called when the mouse moves off the box. In here, we're setting the material back to its original appearance by accessing the material of the Renderer and setting the colour to white.

Let's save the script, switch back to Unity and press play to try this out.

Now, when we move the mouse over one of the boxes, it turns red, and when we move the mouse away it returns to its original colour.

Moving the mouse pointer over a box changes the colour to red

The next thing we want to do is fire the ball at the target.

To do this, we'll select the ball in the hierarchy and add a new script component. We'll call this script TargetSelector.

Creating the Target Selector Script

We'll double click the script to open it in Visual Studio and change it to match the following.

using UnityEngine;

public class TargetSelector : MonoBehaviour
{
    public Camera camera;
    public float forceSize;

    private Rigidbody rigidbody;

    void Start()
    {
        rigidbody = GetComponent<Rigidbody>();    
    }

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = camera.ScreenPointToRay(Input.mousePosition);

            if (Physics.Raycast(ray, out RaycastHit hitInfo))
            {
                if (hitInfo.collider.gameObject.GetComponent<Target>() != null)
                {
                    Vector3 distanceToTarget = hitInfo.point - transform.position;
                    Vector3 forceDirection = distanceToTarget.normalized;

                    rigidbody.AddForce(forceDirection * forceSize, ForceMode.Impulse);
                }
            }
        }
    }
}

We want to fire the ball at the target when the left mouse button is clicked, so the first thing we're doing in the Update method is checking for the mouse click.

If the mouse button has been clicked, the next thing we need to do is find out where exactly the mouse is pointing, so we can fire the ball in this direction.

To do this, we need access to our main camera, so we've added a public field for this.

We're then using the ScreenPointToRay method to create a Ray that goes from the camera through the position in the world that the mouse is pointing.

You can think of a Ray as a line that is emitted from a source in a particular direction. In this case, the source is the camera and the direction is determined by the position of the mouse cursor.

We're then using the Physics RayCast method to see if the Ray passes through anything.

If the Ray has hit something, we need to check that it is one of our targets.

To do this, we're checking to see if the gameobject the Ray has collided with has a Target script component.

If it does, we then calculate the distance between the collision point and our current position.

We're then normalising this to get the direction we want the ball to travel.

The final step is to apply a force in this direction.

To apply the force we need access to the Rigidbody component of the ball, so we've added a private field to hold this.

We're then getting the Rigidbody component in the Start method and assigning it to this field.

We've also added a public field for the desired force size.

We are then applying the force to the Rigidbody in the desired direction. We're specifying the ForceMode as Impulse so that the force is applied instantly.

Let's save the script and switch back to Unity.

We'll select the ball in the hierarchy, and then we'll drag our camera from the hierarchy into the Camera field of our script in the Inspector. We'll also set the force size to 10.

Setting the fields in the Inspector

Let's press play to try this out.

Now we can select a target and click the left mouse button to fire the ball in that direction.

Firing the ball at a target

Also, if you've seen our tutorial on 'Slow Motion', we can add this in to have the ball knock down the boxes in slow motion!

Firing the ball at the boxes in slow motion

That covers everything for this tutorial. We hope that you found it useful. Please leave any questions or feedback in the comments below, and don't forget to subscribe to get notified when we publish our next post.

Thanks.

Comments

Popular posts from this blog

Rotating a Character in the Direction of Movement - Unity Game Development Tutorial

Creating Terrain from Heightmaps - Unity Game Development Tutorial

Simple Movement using Gamepad and Keyboard - Unity Game Development Tutorial