---
title: "Let's Try: Shooting with Raycasts"
content_type: tutorial
url: "https://learn.unity.com/tutorial/let-s-try-shooting-with-raycasts?language=en"
language: en
difficulty: beginner
duration_minutes: 35
unity_version:
  - "5.x"
supported_unity_versions:
  - name: "5.x"
    url: "https://learn.unity.com/tutorial/let-s-try-shooting-with-raycasts.md?language=en&version=5.x"
last_updated: "2026-08-04T14:23:09.000Z"
---

# Let's Try: Shooting with Raycasts

Practice shooting mechanics by using ray casts in Unity, following both video and written instructions.

In this Let's Try  tutorial we will learn how to shoot using Raycasts. This tutorial provides both a video walkthrough and and article version of the instructions.

## Materials

- [Let's Try Project Assets](https://assetstore.unity.com/packages/essentials/tutorial-projects/let-s-try-assets-66207)

## 1. Let's Try: Shooting with Raycasts (Video)

In this Let's Try video tutorial we will learn how to shoot using raycasts.

[Video](http://www.youtube.com/watch?v=AGd16aspnPA)

If you prefer to take this tutorial in article form, please go to the next step.

Questions? Please post in our dedicated forum thread for the Let's Try tutorial series [here.](http://forum.unity3d.com/threads/lets-try-assignments-q-a.426154/)

Download the Let's Try Assets from the Unity Asset Store for free:

![](https://connect-mediagw.unity.com/h1/20190308/p/images/3b0cf00e-8064-4b36-a4f7-d1801ac0cc1d)

## RaycastShootComplete Script

```csharp
using UnityEngine;
using System.Collections;

public class RaycastShootComplete : MonoBehaviour {

    public int gunDamage = 1;                                            // Set the number of hitpoints that this gun will take away from shot objects with a health script
    public float fireRate = 0.25f;                                        // Number in seconds which controls how often the player can fire
    public float weaponRange = 50f;                                        // Distance in Unity units over which the player can fire
    public float hitForce = 100f;                                        // Amount of force which will be added to objects with a rigidbody shot by the player
    public Transform gunEnd;                                            // Holds a reference to the gun end object, marking the muzzle location of the gun

    private Camera fpsCam;                                                // Holds a reference to the first person camera
    private WaitForSeconds shotDuration = new WaitForSeconds(0.07f);    // WaitForSeconds object used by our ShotEffect coroutine, determines time laser line will remain visible
    private AudioSource gunAudio;                                        // Reference to the audio source which will play our shooting sound effect
    private LineRenderer laserLine;                                        // Reference to the LineRenderer component which will display our laserline
    private float nextFire;                                                // Float to store the time the player will be allowed to fire again, after firing


    void Start () 
    {
        // Get and store a reference to our LineRenderer component
        laserLine = GetComponent<LineRenderer>();

        // Get and store a reference to our AudioSource component
        gunAudio = GetComponent<AudioSource>();

        // Get and store a reference to our Camera by searching this GameObject and its parents
        fpsCam = GetComponentInParent<Camera>();
    }


    void Update () 
    {
        // Check if the player has pressed the fire button and if enough time has elapsed since they last fired
        if (Input.GetButtonDown("Fire1") && Time.time > nextFire) 
        {
            // Update the time when our player can fire next
            nextFire = Time.time + fireRate;

            // Start our ShotEffect coroutine to turn our laser line on and off
            StartCoroutine (ShotEffect());

            // Create a vector at the center of our camera's viewport
            Vector3 rayOrigin = fpsCam.ViewportToWorldPoint (new Vector3(0.5f, 0.5f, 0.0f));

            // Declare a raycast hit to store information about what our raycast has hit
            RaycastHit hit;

            // Set the start position for our visual effect for our laser to the position of gunEnd
            laserLine.SetPosition (0, gunEnd.position);

            // Check if our raycast has hit anything
            if (Physics.Raycast (rayOrigin, fpsCam.transform.forward, out hit, weaponRange))
            {
                // Set the end position for our laser line 
                laserLine.SetPosition (1, hit.point);

                // Get a reference to a health script attached to the collider we hit
                ShootableBox health = hit.collider.GetComponent<ShootableBox>();

                // If there was a health script attached
                if (health != null)
                {
                    // Call the damage function of that script, passing in our gunDamage variable
                    health.Damage (gunDamage);
                }

                // Check if the object we hit has a rigidbody attached
                if (hit.rigidbody != null)
                {
                    // Add force to the rigidbody we hit, in the direction from which it was hit
                    hit.rigidbody.AddForce (-hit.normal * hitForce);
                }
            }
            else
            {
                // If we did not hit anything, set the end of the line to a position directly in front of the camera at the distance of weaponRange
                laserLine.SetPosition (1, rayOrigin + (fpsCam.transform.forward * weaponRange));
            }
        }
    }


    private IEnumerator ShotEffect()
    {
        // Play the shooting sound effect
        gunAudio.Play ();

        // Turn on our line renderer
        laserLine.enabled = true;

        //Wait for .07 seconds
        yield return shotDuration;

        // Deactivate our line renderer after waiting
        laserLine.enabled = false;
    }
}
```

## RayViewerComplete

```csharp
using UnityEngine;
using System.Collections;

public class RayViewerComplete : MonoBehaviour {

    public float weaponRange = 50f;                       // Distance in Unity units over which the Debug.DrawRay will be drawn

    private Camera fpsCam;                                // Holds a reference to the first person camera


    void Start () 
    {
        // Get and store a reference to our Camera by searching this GameObject and its parents
        fpsCam = GetComponentInParent<Camera>();
    }


    void Update () 
    {
        // Create a vector at the center of our camera's viewport
        Vector3 lineOrigin = fpsCam.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, 0.0f));

        // Draw a line in the Scene View  from the point lineOrigin in the direction of fpsCam.transform.forward * weaponRange, using the color green
        Debug.DrawRay(lineOrigin, fpsCam.transform.forward * weaponRange, Color.green);
    }
}
```

## ShootableBox

```csharp
using UnityEngine;
using System.Collections;

public class ShootableBox : MonoBehaviour {

    //The box's current health point total
    public int currentHealth = 3;

    public void Damage(int damageAmount)
    {
        //subtract damage amount when Damage function is called
        currentHealth -= damageAmount;

        //Check if health has fallen below zero
        if (currentHealth <= 0) 
        {
            //if health has fallen below zero, deactivate it 
            gameObject.SetActive (false);
        }
    }
}
```

## 2. Let's Try: Shooting with Raycasts (article)

## Introduction

![](https://connect-mediagw.unity.com/h1/20190130/48c99bf2-e804-4b8e-9d91-08b92184a8b1_introgif.gif)

In this tutorial we will learn how to shoot using **_raycasting_**. A ray is an invisible line from point A to point B in the game world. The important point is that this invisible line or ray that is cast into the scene can return information about GameObjects that have been hit by the ray. The GameObjects must have a collider attached in order to register a hit with the ray. When a ray intersects or ‘hits’ a GameObject, the event is referred to as a **RaycastHit**. This hit can tell us certain details about the GameObject and where it was hit, including a reference to the GameObject’s Transform, the length of the ray when it hits something, the point in the world where the hit happened, and more.

In a shooting game like an FPS we aim by looking around with the mouse or the right joystick on a gamepad. When we click the fire button we cast a ray which creates an invisible line from the camera - the player’s eye as far as the game is concerned - forward into the game world so that whatever they look directly at, they can shoot.

![](https://connect-mediagw.unity.com/h1/20190130/85f3112c-1364-43c2-a97a-a48b9707c217_Raycast_Image_1)

## Downloading The Assets

If you have not yet downloaded and imported the asset package please [click here](https://www.assetstore.unity3d.com/en/#!/content/66207) to download it.

- Download and import the assets.

Once you have downloaded and imported the assets into your project, in the folder **Scenes** you will see a scene called **ShootingWithRaycasts**. This is the version of the scene which is not completed that we will be working in. There is also a completed version of the scene in the **Completed Scenes** folder.

## What We will Build

When we have completed this tutorial, it will match the completed scene. To understand what we intend to build, let’s open the completed scene first.

- Open **CompletedScenes** > **RaycastShootComplete**.

![](https://connect-mediagw.unity.com/h1/20190130/e15a85f3-3357-4ccb-93bf-f2bde942489e_1_completedscene.png)

In the completed scene we have a first person character controller called **FPSController** from Unity Standard Assets. We have added a weapon object as a child, named Gun. Ensure that in the Hierarchy you have expanded the FPSController parent GameObject, as well as the FirstPersonCharacter parent GameObject in order to see this. When we rotate the camera using the mouse, the weapon will follow the direction that the camera is looking.

![](https://connect-mediagw.unity.com/h1/20190130/d9d85500-54cd-4e31-b5d2-694b286c436c_3_fpscontroller.png)

We have also added a **UI canvas** with a target reticle image which is this red dot that we see here.

![](https://connect-mediagw.unity.com/h1/20190130/95793240-fb01-485b-91ff-2daa70d2e779_4_ui_canvas.png)

To see how this works, play the scene and test.

- Play the scene and look around with the mouse.
- Click the left mouse button to fire.

In play mode you can see in the **Scene View** that we have a **_green line_** which represents the direction that the player is aiming in. This is not the raycast. This is a representation of where the raycast will be that we have added to the scene using a visualizing and debugging tool. If we fire we can hit the boxes and apply physics forces to them. If we shoot them three times they will be deactivated.

If we look at the **Scene View** while firing we can see two lines. The green line represents the direction that the player is aiming in from the center of the camera, marked by the red reticle dot.

The **_pink line_** is the visible laser that we see in the game view which is being rendered from the end of the gun to the point that the player hit with the raycast.

![](https://connect-mediagw.unity.com/h1/20190130/48623a0d-cd51-4029-baf2-e8f25c2179d6_5_2lines.png)

- Exit Play Mode.

## Creating The Shooting Script

We will start by closing the completed scene and opening the scene **ShootingWithRaycasts**.

- In the **Scenes** folder double click **ShootingWithRaycasts** to open it.

The first thing that we will do is create a new script which we will use for our gun. We will call this script **_RaycastShoot_**.

- In the **Project View** select the **Scripts** folder and click the **Create** button.
- Choose **C# Script**.
- Name the new script **RaycastShoot**.

![](https://connect-mediagw.unity.com/h1/20190130/a2d4ed26-94ab-4835-bf68-3511b19bf1a1_5_cscriptcreate.png)

Next, we will attach the new script to our **Gun** GameObject.

- Expand the child object **FirstPersonCharacter** which holds the camera and select the **Gun** GameObject.
- Drag the **RaycastShoot** script from the scripts folder to the Gun in the **Hierarchy**.

![](https://connect-mediagw.unity.com/h1/20190130/964581fa-39af-4741-a544-d3386d242748_6_drag_rcs.png)

## Declaring Variables

Now let's get our script ready for editing.

- Double click on the **RaycastShoot** script to open it for editing.

Next we will declare a series of public variables and initialize their values. Initializing a variable will set its initial default value.

- Declare a public int called _gunDamage_ and initialize its value to 1.
- Declare a public float called _fireRate_ and initialize its value to .25.

```csharp
public int gunDamage = 1; 
public float fireRate = .25f;
```

_gunDamage_ will determine how much damage is applied to an object when it is shot. This will interact with a simple health script attached to our TargetBox objects called ShootableBox. ShootableBox will be explained later in the tutorial. _fireRate_ will control how often the player can fire their weapon. If the player has just fired they will have to wait .25 seconds before they can fire again.

- Declare a public float called _weaponRange_ and initialize that to 50.
- Declare a public float called _hitForce_ and initialize it to 100.

```csharp
public float weaponRange = 50f; 
public float hitForce = 100f;
```

The variable _weaponRange_ determines how far our ray will be cast into the scene. Initializing it to 50 means that our weapon will have a range of 50 units. If our raycast intersects an object with a rigidbody component attached we will apply force to it, the amount of which will be defined by our _hitForce_ variable.

- Declare a public Transform called _gunEnd_.

```csharp
public Transform gunEnd;
```

_gunEnd_ will be the Transform component of an **empty GameObject** which will mark the position at which our laser line will begin. This empty GameObject will be positioned just in front of the barrel or ‘end’ of the gun so that the laser appears to fire from there.

- Declare a private Camera variable called _fpsCam_. _fpsCam_ will hold a reference to our first person camera. We will use this to determine the position the player is aiming from.

```csharp
private Camera fpsCam;
```

- Declare a private WaitForSeconds variable called _shotDuration_ and initialize it using a new **WaitForSeconds** object which will have a duration of .07 seconds.

```csharp
private WaitForSeconds shotDuration = new WaitForSeconds(.07f);
```

We will use this variable _shotDuration_ to determine how long we want the laser to remain visible in the game view once the player has fired. The function controlling the display of the laser in the game will be a [Coroutine](https://docs.unity3d.com/ScriptReference/Coroutine.html) object to determine how long we want the laser to remain visible in the Game View for, once the player has fired. By declaring and caching the WaitForSeconds now, it will be stored in memory and re-used instead of creating a new WaitForSeconds object each time we fire. This will help optimize memory performance.

- Declare a private AudioSource variable called _gunAudio_.

```csharp
private AudioSource gunAudio;
```

This will hold a reference to an AudioSource that we already have attached to our gun, which we will use to play our shooting sound effect when the player fires.

- Declare a private LineRenderer variable called _laserLine_.

```csharp
private LineRenderer laserLine; 
```

The [ LineRenderer ](https://docs.unity3d.com/ScriptReference/LineRenderer.html) takes an array of 2 or more points in 3D space and draws a straight line between them in the game view.

- Declare a private float variable called _nextFire_.

```csharp
private float nextFire; 
```

_nextFire_ will hold the time at which the player will be allowed to fire again after firing.

At this stage your script should look like this:

```csharp
using UnityEngine;

using System.Collections;

public class RaycastShoot: MonoBehaviour {

    public int gunDamage = 1;                                            

    public float fireRate = .25f;                                        

    public float weaponRange = 50f;                                        

    public float hitForce = 100f;

    public Transform gunEnd;





    private Camera fpsCam;

    private WaitForSeconds shotDuration = new WaitForSeconds(.07f);

    private AudioSource gunAudio;

    private LineRenderer laserLine;

    private float nextFire;    



    void Start () 

{



    }

    void Update () 

{



    }

}
```

## Getting Component References

In the **Start** function we will set up our component references to our _laserLine_ (LineRenderer), _gunAudio_ (AudioSource) and our _fpsCam_ (Camera).

- Get and store a reference to our LineRenderer component in our variable laser line.
- Get and store a reference to our AudioSource in gunAudio.

```csharp
void Start () 
    {
        laserLine = GetComponent<LineRenderer>();
        gunAudio = GetComponent<AudioSource>();
    }
```

This script is attached to our Gun GameObject, but we need to store a reference to the Camera component on the Gun’s parent GameObject FirstPersonCamera. To do this, we will use [GetComponentInParent ](https://docs.unity3d.com/ScriptReference/GameObject.GetComponentInParent.html) to find the component on the parent object, storing a reference in our Camera variable _fpsCam_.

- Get and store a reference to the Camera in our _fpsCam_ variable using _GetComponentInParent_

```csharp
fpsCam = GetComponentInParent<Camera>();
```

_GetComponentInParent_ will search first the GameObject that it is attached to then each GameObject in its parent hierarchy moving recursively upwards one GameObject at a time. It will stop and store a reference to the first component of the specified type that it encounters.

## Controlling Player Fire Rate

The core of our code will be written in the _Update_ function. Here we will handle user input, check if the player can fire and ultimately apply physics force to any GameObject with a Rigidbody hit by the ray.

We need to check if the player has pressed the "Fire1" button and if enough time has passed since they last fired. Each time the player fires we need to track the current game time and then add to it the value stored in _fireRate_, our shot frequency public variable. We store this sum in our private variable called _nextFire_. This is why in our if statement we need to check if the value of the current game time has exceeded our _nextFireTime_, meaning the player can fire once more.

- Add an if statement to check if the Fire1 button is currently held down and _Time.time_ is greater than the value stored in our _nextFire_ variable.
- If that if statement evaluates to true then we will reset our _nextFire_ time by setting _nextFire_ to equal _Time.time_ plus _fireRate_.

```csharp
if (Input.GetButtonDown ("Fire1") && Time.time > nextFire) 

{

     nextFire = Time.time + fireRate;

}
```

## Activating The Shooting Effects

Now it's time to turn on and off our laser effect. We will do this using a [coroutine](https://docs.unity3d.com/Manual/Coroutines.html)

- Declare a new private function that returns IEnumerator called _ShotEffect_.
- In _ShotEffect_, call the _Play_ function of our _gunAudio_ AudioSource. This will play the AudioClip assigned to gunAudio. This is a shooting sound effect that has already been assigned in the editor.

```csharp
private IEnumerator ShotEffect()

{

    gunAudio.Play ();

}
```

- On the next line within _ShotEffect_, enable the LineRenderer _laserLine_.

```csharp
laserLine.enabled = true;
```

We want our coroutine to wait - in this case for .07 seconds - before it turns our laser line back off.

- Tell our coroutine to yield and return our WaitForSeconds variable _shotDuration_ which will cause our coroutine to wait for .07 seconds.
- Once it's done waiting, disable the _laserLine_.

```csharp
yield return shotDuration;
laserLine.enabled = false;
```

At this point, your code for _ShotEffect_ should look like this, please check your code before continuing to read.

```csharp
private IEnumerator ShotEffect()
{
    gunAudio.Play ();
    laserLine.enabled = true;

    yield return shotDuration;

    laserLine.enabled = false;
}
```

We want to start this coroutine whenever the player fires, which we will detect in the _Update_ function.

- Back in _Update_, within the braces for our if statement and below the line in which we set nextFireTime we will call _StartCoroutine_ and specify _ShotEffect_.

```csharp
StartCoroutine(ShotEffect());
```

## Raycasting From The Camera

Next, we need an origin point for our ray. In order for the player to be able to aim accurately we want this point to always be at the center of our camera. We will achieve this using [ \*\*\_ViewportToWorldPoint\*\*](https://docs.unity3d.com/ScriptReference/Camera.ViewportToWorldPoint.html). In this case we are passing in a new Vector3 which is set to .5 on the X axis, .5 on the Y axis, and 0 on the Z axis. This function takes a position relative to the camera's viewport, and converts it to a 3 dimensional point in World space. By giving this function a Vector3 value, we can use the X and Y values of the Vector3 to determine where on the viewport rectangle our ray should start. Passing in 0.5 on the X and Y axes specifies a point directly in the center of the view, where we expect the player to aim from.

- In _Update_, declare a new Vector3 variable called _rayOrigin_.
- Set it’s position to the center of the screen using _ViewPortToWorldPoint_.

```csharp
Vector3 rayOrigin = fpsCam.ViewportToWorldPoint (new Vector3 (.5f, .5f, 0)); 
```

At this point your script should look like this:

```csharp
using UnityEngine;

using System.Collections;

public class RaycastShoot: MonoBehaviour {

    public int gunDamage = 1;                                            

    public float fireRate = .25f;                                        

    public float weaponRange = 50f;                                        

    public float hitForce = 100f;

    public Transform gunEnd;





    private Camera fpsCam;

    private WaitForSeconds shotDuration = new WaitForSeconds(.07f);

    private AudioSource gunAudio;

    private LineRenderer laserLine;

    private float nextFire;    



    void Start () 

{

        laserLine = GetComponent<LineRenderer> ();

        gunAudio = GetComponent<AudioSource> ();

        fpsCam = GetComponentInParent<Camera> ();

    }

    void Update () 

{

        if (Input.GetButtonDown("Fire1") && Time.time > nextFire) 
        {
            nextFire = Time.time + fireRate;

                   StartCoroutine (ShotEffect());

                   Vector3 rayOrigin = fpsCam.ViewportToWorldPoint (new Vector3(0.5f, 0.5f, 0.0f));
        }

    }

}
```

To understand this better, let's return to Unity and take a look at the camera's **_view frustum_**.

- Return to the Unity Editor.
- In the Hierarchy expand the **FPSController** GameObject and select the FirstPersonCharacter GameObject which has our Camera component attached.
- Temporarily de-activate the **Directional Light** by selecting it in the Hierarchy and un-checking its **active checkbox** at the top of the Inspector. The Directional Light is a child of the **Lighting** GameObject, which is a child of **Environment**.

![](https://connect-mediagw.unity.com/h1/20190130/9e90a508-aeac-4ce6-ac3a-857bbdece2ca_dirlightoff.png)

This will simply allow us to see the Camera frustum more easily in this light styled environment, we will re-activate it shortly, but for now, de-activate it, then re-select the **FirstPersonCharacter** GameObject.

- Place your mouse over the **scene view** and press **F** to **frame selected**.
- Use the **alt or option key** to pan the view around and see the camera's **view frustum**.

![](https://connect-mediagw.unity.com/h1/20190130/c4c28b58-91a7-4f35-a0b4-2e4f73062290_7_frustum.png)

The camera's _view frustum_ is a shape which represents the viewable area of the camera. This shape is a four sided cone or pyramid with the tip cut off. The near end of it is the camera’s near clip plane. The larger rectangle farther away is the far clip plane. Only GameObjects within the camera's frustum are rendered. This frustum sets the boundaries for the camera's view. _ViewportToWorldPoint_ uses viewport space. This space is normalized and relative to the camera.

![](https://connect-mediagw.unity.com/h1/20190130/4492b8fe-2929-46f2-83b8-9e3dc4ab5644_0505_lines.png)

The bottom left of the viewport is defined as 0,0. The top right is defined as 1,1. By specifying a value of 0.5 along the X axis and 0.5 along the Y axis we are getting a point at the very center of our camera’s viewport. Passing in 0 for Z axis means that it will be 0 units away from the camera's facing direction.

With that done, let's continue writing our script.

- Turn the main Directional Light back on and return to the script editor.

## Storing Hit Information

We now need to declare a variable to hold the information returned from our ray if it hits a GameObject with a collider attached. This variable will need to be a RaycastHit type of variable, and we will name it _hit_.

- In Update we will declare a RayCastHit called _hit_. We will use it to store information about whatever we hit with our Raycast.

```csharp
RaycastHit hit;
```

## Setting The Line Start Point

Now we need to determine start and end positions for our laserLine when the player fires. The first thing we need to do is to establish the initial position of the line. In order to draw a line with the LineRenderer we need to specify at least two points for it to draw between.

- Set the first point or position 0 to _gunEnd.position_.

```csharp
laserLine.SetPosition(0, gunEnd.position);
```

Remember, gunEnd is the empty GameObject that we will attach to the end of our gun in the scene. This empty GameObject will give us the current position in world space for the end of our Gun. We can safely set this here, as every time the player fires we want to start the LineRenderer at the end of the gun.

## Casting The Ray

Continuing within our _Update_ function, on the next line we will use _Physics.Raycast_ to cast our ray.

- Add an if statement.
- In the if statement parenthesis, call _Physics.Raycast._

```csharp
if (Physics.Raycast(rayOrigin,fpsCam.transform.forward, out hit, weaponRange))
```

We will use the results of this raycast for a number of things. The first thing we will use it for is to determine where the end point of our laser line will be. Later we will also use the results of this raycast to apply physics forces to the GameObject that it intersected. We will also use the results to deal damage to it if it has a damage script attached.

![](https://connect-mediagw.unity.com/h1/20190130/5c43369b-4a8a-4981-9f42-4101f65011fa_1.png)

_Physics.Raycast_ returns a boolean, meaning that if it hits something it will evaluate to true. By placing it in our if statement this means that the code that follows will only be executed if our raycast hit something.

The first parameter that we will pass in when casting our ray is _rayOrigin_. This will be the point in our world where our ray will begin, in this case the center of our camera’s viewport, which we have already stored in our variable _rayOrigin_.

The direction which we will cast our ray in will be the forward direction of our camera _fpsCam_, so we pass in _fpsCam.transform.forward_ for the second parameter of the raycast.

We will store additional information about the object that we hit including its rigidbody, collider and surface normal in our RaycastHit variable _hit_. Using the out keyword allows us to store additional information from a function, in addition to its return type.

Finally we will pass in _weaponRange_ which is the distance over which we want to cast our ray, in this case 50 units.

## Two Possible End Points

There are two possible positions for the end of our laser. The first is the position of whatever we hit with our raycast, but it's possible that if we fire into the sky our raycast will hit nothing and we need to account for that behavior as well. In the case where we have hit something with our raycast we will set the second position of our line to _hit.point_.

- Within the brackets of the if statement for our raycast, call _laserLine.SetPosition_ and pass in _hit.point_

```csharp
if (Physics.Raycast (rayOrigin, fpsCam.transform.forward, out hit, weaponRange)) { laserLine.SetPosition (1, hit.point); }
```

In the case where our raycast has not intersected with anything and therefore our first if statement returns false, we will use an else to set the position of the end of our line 50 units away from _rayOrigin_, in the forward direction of our camera.

- Add an else statement.
- Set the end position of the line to 50 units forward from the camera, by multiplying the forward direction of _fpsCam_ by the _weaponRange_ variable.

```csharp
else
{ 
laserLine.SetPosition(1, fpsCam.transform.forward * weaponRange); 
} 
```

- Save the script and return to Unity.

At this point your script should look like this:

```csharp
using UnityEngine;
using System.Collections;

public class RaycastShoot : MonoBehaviour {

    public int gunDamage = 1;
    public float fireRate = 0.25f;
    public float weaponRange = 50f;
    public float hitForce = 100f;    
    public Transform gunEnd;

    private Camera fpsCam;                                                
    private WaitForSeconds shotDuration = new WaitForSeconds(0.07f);
    private AudioSource gunAudio;
    private LineRenderer laserLine;
    private float nextFire;


    void Start () 
    {
        laserLine = GetComponent<LineRenderer>();

        gunAudio = GetComponent<AudioSource>();

        fpsCam = GetComponentInParent<Camera>();
    }


    void Update () 
    {
        if (Input.GetButtonDown("Fire1") && Time.time > nextFire) 
        {
            nextFire = Time.time + fireRate;

            StartCoroutine (ShotEffect());

            Vector3 rayOrigin = fpsCam.ViewportToWorldPoint (new Vector3(0.5f, 0.5f, 0.0f));

            RaycastHit hit;

            laserLine.SetPosition (0, gunEnd.position);

            if (Physics.Raycast (rayOrigin, fpsCam.transform.forward, out hit, weaponRange))
            {
                laserLine.SetPosition (1, hit.point);
            }
            else
            {
                laserLine.SetPosition (1, rayOrigin + (fpsCam.transform.forward * weaponRange));
            }
        }
    }


    private IEnumerator ShotEffect()
    {
        gunAudio.Play ();

        laserLine.enabled = true;

        yield return shotDuration;

        laserLine.enabled = false;
    }
}
```

## Rendering The Visible Laser Effect

Now let's set up our LineRenderer which will make our shots visible in the **Game View**.

- Select the **Gun** GameObject and choose _GameObject > Create Empty Child_.
- In the inspector rename this new child object to **GunEnd**.
- Apply a label to GunEnd so that we can see it easily in the **scene view**.

![](https://connect-mediagw.unity.com/h1/20190130/15b8f0e8-51d9-47ce-b48a-4b5dd6f56178_10_gunlabeled.png)

Now let's position the GunEnd object in front of the barrel of our gun.

- Select the GunEnd GameObject
- In its Transform component set the position on the X-axis to 0.36.
- Set the position on the Y-axis to -0.18.
- Set the position of the Z-axis to 1.

![](https://connect-mediagw.unity.com/h1/20190130/a9867a56-b31b-4ed3-8a67-45a872efe696_gunendpositioned.png)

This will position it directly in front of our gun barrel. To make our shots visible in the **Game View** we will use a **_LineRenderer_** component. The LineRenderer will draw a line from the position of gunEnd to the position that the player is aiming using our invisible raycast.

- Highlight the Gun GameObject and click **Add Component > Effects > LineRenderer**.

![](https://connect-mediagw.unity.com/h1/20190130/ace48dd4-eb7f-46fd-933f-dced9c575193_12_addlinerenderer.png)

## Assigning Variables In The Editor & Setting Line Width

Now, we need to assign the _gunEnd_ variable of our RaycastShoot script.

- Drag the GunEnd GameObject to the _gunEnd_ field of RaycastShoot.

![](https://connect-mediagw.unity.com/h1/20190130/7eeed811-35e7-4e26-8638-77ba8bc88b9c_draggunend.png)

Next, let's set the parameters for our line render to make the line a little bit narrower.

- Expand the Parameters section of the LineRenderer component, and set the 'Start Width' and 'End Width' properties to 0.05.

![](https://connect-mediagw.unity.com/h1/20190130/e77aff85-2f9d-4a54-9498-4614a11d0de2_linerendererparams.png)

It's worth noting that we have not assigned a material to the LineRenderer and this is why it will render pink. If we want to change the color of the rendered line, simply drag a material to the element 0 slot in the Materials array. The last thing we need to do before we are done tweaking our LineRenderer component is to disable it.

- Un-check the Enabled checkbox of the 'LineRenderer’ component to make sure that the component is disabled when the game begins.

The RaycastShoot script will enable the LineRenderer when the player fires the weapon, so it should be disabled by default.

## Debugging Raycasts

Raycasts are invisible in both the **Scene View** and the **Game View**. When working with raycasts it can be useful to visualize them in the **Scene View**. We are going to write a simple helper script which will allow us to visualize our raycasts in the scene view. It's worth noting that this script is a development tool and should be removed before creating the final build of your game.

- Highlight the Scripts folder
- Create a new C# script called **RayViewer**
- Drag RayViewer onto the **Gun** GameObject in the **Hierarchy**.
- Select the **Gun** and double click **RayViewer** to open it for editing.

RayViewer will duplicate some of the functionality of RaycastShoot, because its purpose is similar. Instead of casting a ray, we will simply be drawing a line to show where our ray is going in the Scene View.

- Declare a public float variable called weaponRange and initialize it to 50.
- Declare a private Camera variable called fpsCam.

```csharp
public float weaponRange = 50f;
private Camera fpsCam;
```

- In Start use _GetComponentInParent_ to store a reference to our Camera in _fpsCam_.

```csharp
void Start () 
{ 
fpsCam = GetComponentInParent<Camera>(); 
}
```

In _Update_ we will calculate the origin point of our line, then we will draw it using [Debug.DrawRay](https://docs.unity3d.com/ScriptReference/Debug.DrawRay.html) . To calculate the origin point of the line that we will draw using _Debug.DrawRay_ we will use much of the same code that we used to calculate the origin of our ray.

- Declare a new Vector3 called _lineOrigin_. Set _lineOrigin_ to the center of our viewport using _ViewportToWorldPoint_.

```csharp
Vector3 lineOrigin = fpsCam.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, 0.0f));
```

- Call _Debug.DrawRay_ and pass in the start point which is _rayOrigin_, the direction which we want it to go in, which in this case is _fpsCam.transform.forward_, or the forward direction away from our camera.
- For the second parameter multiply fpsCam.transform.Forward by _weaponRange_ which in this case is set to 50. This will set the end point of the line 50 units away from the camera.
- For the third parameter pass in _Color.Green_ to set the color of the line which will be drawn in the scene view.

```csharp
Debug.DrawRay(lineOrigin, fpsCam.transform.forward * weaponRange, Color.green);
```

It's worth noting that because _Debug.DrawRay_ is a debugging tool it will only be visible in the **Scene View**.

- Save the script and return to Unity to test.
- **Play** the scene.

With our scene playing we can see that a green line is drawn from center of the camera, away from it in the **Scene View**. This helps us to visualize where our player will be able to aim.

![](https://connect-mediagw.unity.com/h1/20190130/ead1af44-2724-4099-9a78-4918862af42a_greenlineinsceneview.png)

Now, we can draw the visual effect for shooting but we can't yet affect the object in the game.

## The Target Box

Before we return to our script let's take a look at the object that we want to interact with.

- Expand the **Environment** GameObject in the **Hierarchy window**.
- Select the **Target Box** GameObject.

![](https://connect-mediagw.unity.com/h1/20190130/b3d4336a-70f4-494d-8f10-313d0825d3fa_15_targetbox.png)

In the inspector we can see that the TargetBox object has a script attached to it called **_ShootableBox_**. ShootableBox has a public variable called _currentHealth_ which is set to 3.

- Double click the script in the **script field** of ShootableBox to open it.

![](https://connect-mediagw.unity.com/h1/20190130/3636871a-9c33-4db8-92fb-079eb0ff53c8_16_shootablebox.png)

## The ShootableBox Script

ShootableBox is a simple health script. In it we have a public integer called _currentHealth_, which is initialized to 3.

We have a single public function which returns void called _Damage_. _Damage_ takes an integer as its only parameter called _damageAmount_.

When the _Damage_ function is called we will subtract _damageAmount_ from _currentHealth_.

Next we check if _currentHealth_ is less than or equal to 0.

If it is we will call _gameObject.SetActive(false)_ to deactivate the GameObject that the script is attached to.

In game terms - this simply means we can shoot the box 3 times before it is de-activated, which to the player will make it disappear from the game.

```csharp
using UnityEngine;
using System.Collections;

public class ShootableBox : MonoBehaviour {

    //The box's current health point total

    public int currentHealth = 3;

    public void Damage(int damageAmount)

    {

        //subtract damage amount when Damage function is called

        currentHealth -= damageAmount;

        //Check if health has fallen below zero

        if (currentHealth <= 0) 

        {

            //if health has fallen below zero, deactivate it 

            gameObject.SetActive (false);

        }

    }

}
```

## Applying Damage & Physics Forces To The ShootableBox

Let's return to our RaycastShoot script. In the if statement for our raycast we are going to check if there is a _ShootableBox_ component attached to the GameObject that our raycast hit. We find this by checking the collider which was hit by the ray, and then using _GetComponent_ - here our collider is a shortcut to refer to the GameObject, so it is the same as using _gameObject.GetComponent_. If it is we will call that object’s _Damage_ function and pass in our variable _gunDamage_.

- Declare a variable of the type ShootableBox called _health_.
- Set this to equal _hit.collider.GetComponent\<ShootableBox>()_.

```csharp
ShootableBox health = hit.collider.GetComponent<ShootableBox>();
```

What this means is that if there is a ShootableBox component attached to the collider we hit, it will be stored in our variable health.

- Check if _health_ is not equal to null, meaning there was a ShootableBox component attached to the thing we hit.
- If this statement evaluates to true we will call the _Damage_ function of _health_ and pass in _gunDamage_ as a parameter.

```csharp
if (health != null) 
{ 
health.Damage (gunDamage); 
}
```

_gunDamage_ was the first public integer we declared in this script. It is currently equal to 1.

We only want to apply damage to dynamic objects that we know can be repelled by our laser in game terms, these objects all have something in common - a Rigidbody physics component. As such we will check if one such component is present on the GameObject hit by the ray before we try and apply forces to it.

- Check if there is a Rigidbody component attached to the GameObject we hit with our raycast.
- If there is we will add force to it to move it around. We will do this using the function _AddForce_.
- Add force to the Rigidbody of the object we hit and pass in negative _hit.normal_ multiplied by _hitForce_.

```csharp
if (hit.rigidbody != null)
{
hit.rigidbody.AddForce (-hit.normal * hitForce);
} 
```

[hit.normal](https://docs.unity3d.com/ScriptReference/RaycastHit-normal.html) is the outward direction of the surface we hit. By using negative hit.normal we can add force to the TargetBox in a direction that is the inverse of this, repelling it back from it’s surface. Multiplying it by _hitForce_ allows us to control how much force should be added when we shoot an object.

![](https://connect-mediagw.unity.com/h1/20190130/394b1247-406c-4c9c-8b3b-2cbd6fe17790_hitnormal.png)

- Save the script and return to Unity.

At this point your script should look like this:

```csharp
using UnityEngine;
using System.Collections;

public class RaycastShootComplete : MonoBehaviour {

    public int gunDamage = 1;
    public float fireRate = 0.25f;
    public float weaponRange = 50f;
    public float hitForce = 100f;    
    public Transform gunEnd;

    private Camera fpsCam;                                                
    private WaitForSeconds shotDuration = new WaitForSeconds(0.07f);
    private AudioSource gunAudio;
    private LineRenderer laserLine;
    private float nextFire;


    void Start () 
    {
        laserLine = GetComponent<LineRenderer>();

        gunAudio = GetComponent<AudioSource>();

        fpsCam = GetComponentInParent<Camera>();
    }


    void Update () 
    {
        if (Input.GetButtonDown("Fire1") && Time.time > nextFire) 
        {
            nextFire = Time.time + fireRate;

            StartCoroutine (ShotEffect());

            Vector3 rayOrigin = fpsCam.ViewportToWorldPoint (new Vector3(0.5f, 0.5f, 0.0f));

            RaycastHit hit;

            laserLine.SetPosition (0, gunEnd.position);

            if (Physics.Raycast (rayOrigin, fpsCam.transform.forward, out hit, weaponRange))
            {
                laserLine.SetPosition (1, hit.point);
                ShootableBox health = hit.collider.GetComponent<ShootableBox>();

                if (health != null)
                {
                    health.Damage (gunDamage);
                }

                if (hit.rigidbody != null)
                {
                    hit.rigidbody.AddForce (-hit.normal * hitForce);
                }
            }
            else
            {
                laserLine.SetPosition (1, rayOrigin + (fpsCam.transform.forward * weaponRange));
            }
        }
    }


    private IEnumerator ShotEffect()
    {
        gunAudio.Play ();

        laserLine.enabled = true;

        yield return shotDuration;

        laserLine.enabled = false;
    }
}
```

## Testing Our Shooting Mechanic

As we can see our Target Box GameObjects already have a Rigidbody component attached. They should be ready to shoot.

![](https://connect-mediagw.unity.com/h1/20190130/f9ac8d0e-1912-4a84-8c85-610a2a0b77a3_17_targetboxinspector.png)

- Play the scene, then try to fire at the boxes.

Our shooting is working, but as you may have noticed it's still a little bit difficult to aim.

## The Target Reticle UI

Let’s add the final component which will be our red reticle. The reticle UI is very simple. It's a small red UI Image in the center of the screen.

- Choose **GameObject > UI > Image**.

![](https://connect-mediagw.unity.com/h1/20190130/aded83fe-32ba-491c-8518-bf1f73138696_createimage.png)

- Switch the scene view into **2D Mode**.

![](https://connect-mediagw.unity.com/h1/20190130/7405451c-83e8-4324-9b0c-39637f77c843_2dbutton.png)

- With the mouse cursor over the Scene View, Push the **F key** to frame selected on our image.
- Zoom out using the Mouse wheel so you can see that we have a white image in the lower left hand corner of our screen. You can also see this in the Game View.

![](https://connect-mediagw.unity.com/h1/20190130/2c4ea09c-2fab-47c7-a3d9-5093119efe64_whiteuiimage.png)

- Change the image’s color. With the image selected click on the **Color** field in the image component.

![](https://connect-mediagw.unity.com/h1/20190130/6dde8125-31cf-4a34-b38f-1e123846d82d_20_colorpickerhighlighted.png)

- Drag the color swatch all the way to the upper right corner to make the image red.

![](https://connect-mediagw.unity.com/h1/20190130/c31fb169-c569-455e-a8d9-ff159f025e60_21_colorpickerred.png)

- Anchor the image to the center of the screen by opening the **Anchor Presets**, holding down the **alt or option key** and clicking on the **center preset**.

![](https://connect-mediagw.unity.com/h1/20190130/3a75fcb8-ecb9-4105-bdff-2b0b1b03ffd5_22_anchorpreset.png)

- In the **Rect Transform** click on the **Width** property and set it to 5.
- Click on the **Height** property and set that to 5 as well.

![](https://connect-mediagw.unity.com/h1/20190130/74507994-7661-496b-8523-761640f421ee_23_widthheight.png)

- Play the scene and test again.

As we can see we have our reticle anchored in the center of our screen and we can move it around, and aim and fire much more easily.

## Conclusion

That's the basics for shooting with Raycasts. If you want more game mechanic focused tutorials please check out our other Let's Try tutorial assignments.
