Unity Raycasting

In the last lesson, we added our enemy soldier to the scene, giving us something to fire at. In this lesson, you'll learn how to write the code to get the player to fire at this soldier enemy.

 

Fire at the Enemy Soldier and Cause Damage

If you remember, we left off the code for our GunFire script at this:

Unity C# code player fire gun

When we fire at this soldier enemy, we need to write code to see if our shot hit or missed. To do that, we can use Raycasting. This is not the same Raycasting as on expensive graphic cards, which is to do with how light bounces off surfaces. The Raycasting we're going to use is just casting out a straight line (a ray) and see if it interacts with our enemy.

Return to the code for your gun shot, which was your GunFire script. We're going to need a few more variables for this. So add these below the ones you already have:

private Transform mainCamera;
[SerializeField] float range = 250;
private int damage = 5;

We're going to be shooting rays out of the main camera, where our gun is. This is of type Transform, which we need to get the position of the camera. We've called the variable mainCamera. The range variable is a float and tells us how far we can cast the ray. In other words, how far we can shoot. We've set this to be a default value of 250. This is entirely arbitrary, however, and you can change this to anything you like. The third variable is called damage. This is how much damage the enemy takes with each shot. (We'll write an Enemy Health script soon. When the enemy's health gets to zero, we can kill him off.)

To handle the code for Raycasting, we'll have a new method. Just below the curly brackets of IEnumerator FireGun(), add this method:

void GunshotHitCheck() {
}

This is just a void method that we've called GunshotHitCheck. (It's void because we don't need to return a value.) We can call this method from the Update method. Add this call just below the start coroutine line:

GunshotHitCheck();

Here's what your code should look like so far (we've contracted the FireGun and Start code):

Unity C# code with some variables and a method set up

The first thing to do is to find the main camera. We can do this with a handy method called FindGameObjectWithTag. As its name suggests, you can use this to find one of your game objects with a specific tag. The camera that is attached to our player, First person camera, already has a tag. It has the tag name MainCamera, which is useful, as it means that we don't need to create a new tag.

To get a reference to the main camera, add the line in bold to your Start method, just below the gunAnim line:

void Start()
{

gunshot = GetComponent<AudioSource>();
gunAnim = GetComponent<Animator>();
mainCamera = GameObject.FindGameObjectWithTag("MainCamera").transform;

}

We need the position of the camera, so we use transform at the end of the line. This is the same transform that we've been manipulating in the Inspector for various objects and our animation.

Now jump to your GunshotHitCheck method. Inside the curly brackets of the GunshotHitCheck method add this code, then we'll go through it: (You can copy and paste it, if you want.)

Ray rayFrom = new Ray(mainCamera.position, mainCamera.forward);
RaycastHit hit;

if (Physics.Raycast(rayFrom, out hit, range))
{

if (hit.collider.CompareTag("Enemy-1"))
{

Debug.Log("HIT: " + damage);

}
else {

Debug.Log("MISS");

}

}

Let's go through it.

The first line of the method is this:

Ray rayFrom = new Ray(mainCamera.position, mainCamera.forward);

This new variable is of type Ray. We've called it rayFrom. After the equal sign, you need a new Ray object. In between the round brackets of Ray, we get the position of our mainCamera. Then we type a comma. After the comma, we specify a direction the ray will shoot. We need forward, obviously, because it would be a strange and dangerous gun that fired backwards. Remember, though, our gun is attached to the camera. Whichever way the camera is pointing is the way the gun is pointing. (The gunsight we added is the middle of the camera and is where the ray is coming from. It will be going forward from there.)

The next line is this one:

RaycastHit hit;

This is the actual Raycast. We've called it hit. Just think of it as a line.

We then have an if statement. This:

if (Physics.Raycast(rayFrom, out hit, range))
{
}

Raycasts are Physics objects. Which is why you need to start with Physics.Raycast. In between the round brackets of Physics.Raycast, you need at least three things: where your ray is coming from, your Raycast object, and the range of the ray. The peculiar part is the keyword out before hit. This is output. The hit variable will contain a lot of information about the Raycast. Fortunately, we only need the collider information of the hit variable.

But the reason it's all wrapped up in an if statement is because Physics.Raycast returns a Boolean value - whether or not the ray hit anything.

If the ray did hit something, we need to detect what. We add another if statement. This one goes between the curly brackets of the first if statement:

if (hit.collider.CompareTag("Enemy-1"))
{

Debug.Log("HIT: " + damage);

}
else {

Debug.Log("MISS");

}

Inside the round brackets of this if statement, we have this:

hit.collider.CompareTag("Enemy-1")

So, we need the collider information back from the hit variable. The collider has a method called CompareTag. In between the round brackets of CompareTag we type the tag name we came up with earlier for the enemy, which was Enemy-1. This needs to go between double quotation marks.

If it's true that the ray hit something with the tag name Enemy-1 then we can do something. For now, we just print to the console. Later, we'll delete the debug lines and reduce the health of the enemy.

But your code should look like this (the new parts are highlighted):

Unity C# code for a raycast to use as a gunshot

Save your code and go back to Unity. We now need to set up a tag called Enemy-1. So, with your Soldier selected in the Hierarchy, take a look at the Inspector on the right:

Inspector showing an untagged game object

Click the dropdown at the top, next to Tag (it's Untagged, at the moment). Select Add Tag from the menu:

Unity menu showing the Add Tag item highlighted

When you click on Add Tag, you'll see a new area appear. Click the plus button indicated in the image below:

The Tags and Layers screen

When you click the plus button, you'll see a box appear where you can type a name for your new tag. This one:

Saving a new tag

Type Enemy-1 as the tag name and click Save. Your tag will then be added to Unity's list of tags:

A new tag added to the list of tags

Unfortunately, you won't be taken back to where you were before. So click back on your Soldier in the Hierarchy. Now click the dropdown again in the Inspector. You should see your new tag name on the list. Select Enemy-1:

Menu showing new tag added to the list of Unity tags

With the Enemy-1 tag set up, try it out. First click on the Console tab so that you can see what's happening. (If you can't see a Console, click the Window item on the menu at the top of Unity. From the Window menu, select Panel > Console.) Now play your game. Shoot at your enemy. The console will look like this:

the console window in Unity

The numbers on the right, highlighted, are how many times you've hit or missed.

We'll come back to our Raycast code and deduct health from the enemy. Now, we'll add an Enemy Health script. If the health of the enemy reaches zero, we can play the Dying animation.

<--Back to the Unity 3D Course Contents Page