Unity Accuracy Rate Algorithm

One thing you may have noticed with your soldier is that he hits you with every shot. His accuracy rate is 100%. Which means he never misses. You may, however, want to set different accuracy rates for your enemies.

The coding to set the accuracy rate for enemies is a little bit tricky. But on the positive side, you will learn how to add a slider to the Inspector!

Actually, the slider is the easy part. Go back to your EnemyHealth script. Add this to the top of your code, where all the variables are:

[Range(1, 10)] public int accuracyRate = 5;

The part that gets you a slider in the Inspector is this:

[Range(1, 10)]

So you just type Range. In between the round brackets of Range, you need the lowest value you want for your slider then, after a comma, the highest value. All of this has to go between a pair of square brackets [].

The next thing you need is a variable. We want an integer. It's public so that it shows up in the Inspector. The variable is called accuracyRate and it's set to a default value of 5. This will set the slider on 5, our halfway point. But you can change it to any number between the 1 and 10 of our Range.

Save your work and go back to Unity to see what it looks like. Make sure your Soldier is selected in the Hierarchy. Now have a look at the Inspector to see the new slider:

Unity Inspector showing a custom slider

You can see the Accuracy Rate slider at the bottom of the EnemyHealth script, just above the Add Component button, in the image above. It's set to a value of 5, that default from our code. If you were to click on the second soldier you added, you'd see that it too has an Accuracy Rate slider. This means that you'll be able to set different values for your enemies. Whatever rate you set on the slider will end up in that accuracyRate variable in the code.

Now to do something with the accuracyRate variable. As it is, it's not doing anything. This is where it gets tricky!

If you set the slider to 8, you're saying that you want your soldier to fire with an accuracy rate of 80%. Set it to, say, 3, and you want the soldier to fire with an accuracy rate of 30%, meaning 3 shots out of ten will hit their target, us. The question is, how do you convert all of this to code?

Well, suppose we wanted to be accurate to 80%. If so, 8 shots will hit us out of 10 shots fired. We could generate a random number between 0 and 9 (10 numbers):

int ranRange = Random.Range(0, 9);

Then reserve 2 numbers for the miss. The other 8 will be the hit:

if (ranRange == 0 || ranRange == 1)
{

isHit = false;

} else {

isHit = true;

}

The code above reserves the numbers 0 and 1 from the random numbers. If the random number generated is indeed a 0 or a 1 then we can set isHit to false. If it's one of the other 8 numbers, however, then we can set isHit to true. This would get us our 80% hit rate.

You'll be glad to know that we have a method you can copy and paste. Click the link below to open up the code in a new tab.

DidGunshotHit Method

Select all the text in the file and paste it into your EnemyHealth script just below the final curly bracket of the class.

Notice that the method is a Boolean rather than the void methods we've been using so far:

private bool DidGunshotHit(int accuracy)

This means you need to return a bool value for the method to work:

return isHit;

In between the round brackets of this DidGunshotHit method, we're passing in the accuracy rate.

Note also that we're using a switch statement to get the accuracy level from the slider:

switch (accuracy)

We have a section on switch statements here, if you're not sure about them:

C# Switch Statements

Now we need to call this DidGunshotHit method from somewhere. But where?

In our game, we don't get to see a bullet. So it doesn't really matter that the soldier hits us all the time. We can just use our new method on the PlayerTakeDamage method. If our DidGunshotHit returns true, we can take damage points off the player. If it returns false, then we won't take any damage points off the player.

So, locate this line in your FireGun method:

player.GetComponent<PlayerHealth>().PlayerTakeDamage(damage);

Change it to this:

bool isPlayerHit = DidGunshotHit(accuracyRate);

if (isPlayerHit)
{

player.GetComponent<PlayerHealth>().PlayerTakeDamage(damage);

}

First, we call our DidGunshotHit method. The value it returns is placed inside of the isPlayerHit bool. We then test what isPlayerHit is in an if statement. If it's true then call PlayerTakeDamage. If it's false then nothing will happen to the player - it won't take a hit.

Your Enemy Health script should look like this (we've contracted some of the code, because it's getting a bit long):

Unity C# code for an accuracy rate algorithm

Save your code and go back to Unity. Each soldier in your scene should now have an accuracy slider. Set them to different rates. Watch your health score. You should find that you don't get hit after every shot (unless you've set the sliders to 10).

 

And that concludes this section on FPS mechanics. Obviously, there's a lot more we could do here. And we haven't even covered lighting yet. Or put a roof over our heads. (We hope to have an entire section on lighting soon. But Unity are moving to a different lighting system, so we'll hold off until they bring it out.)

We hope to bring you more tutorials on Unity 3D programming soon.

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