Tuesday, June 16, 2015

Tutorial: Grenade

Today will be a tutorial lesson, most of the code was made by me by recycling old code from previous experiments, and scripts, the rest was having to google snippets. I will add that this is not perfect, there is some tweaking that needs to be done. 

First we need a grenade model, you can get this one for free, it well done with good poly count and texture resolution: https://www.assetstore.unity3d.com/en/#!/content/8556

<NOTE: If this asset is removed try and find another for free, or if you wish spend the money, if you wish to forgo all this, just create a sphere scale it down to realistic level, and change the Mesh Renderer materials to a noticeable color. The create as a prefab.>

And now, we need a sound: http://www.freesfx.co.uk/soundeffects/explosions/?p=6
<NOTE: You will need an account, its free, and they have a good selection of various things.>
Download the Explosion, Small .mp3

Let me explain what we are doing. We will make two scripts, one to regulate explosion: the time it takes for the detonation to occur, the damage to be applied based on radius, then the clean up where we remove the prefab and the particle. The second script is for the spawning of the grenade, and the subsequent application of physics to make it move, as well as a GUI to keep track of quantity. This will all be done in C#:

For the first script lets name it: GrenadeExplosion

Since this is the more important script lets explain the mechanics. First we need the variables for the cinematics, the particle to be played for explosion, and variables for sound. For the mechanics end we need: timer at zero to be incremented till it reaches its trigger point: timerTD. Now, we need a radius of how much the grenade can reach, and how much damage the grenade can do. And finally, collidersInRange and grenade origin. This is to check if any colliders are in range of the blast radius.

Let me explain how all this works in the Update() function:

The first thing we have to do is start the timer: timer +=1 * Time.deltaTime
Now we have to see if the timer matches the threshold to detonate the grenade: if (timer >= timeTD)
If it does the explosion will take place. But! The sound is played first. But! The Update() is a constant loop, and the sound will keep playing till the prefab is destroyed, creating a distorted effect of multiple audio clips. So we need to check this error:
audioPlaying.clip = exploSound;

If there is no audio playing, play the explosion sound clip. Next, we have to check how many colliders are in range of the grenade prefab:
collidersInRange = Physics.OverlapSphere (grenadeOrigin, explosiveRadius);

Now for the explosion:
insta = (GameObject)Instantiate (explosivo, transform.position, transform.rotation);

We are making a temporary variable called insta that will hold the the particle for the explosion and spawn it at the location and rotation of the grenade prefab.

Now we have to apply damage. So we make a loop to keep track of all colliders in the range of the grenade.

foreach (Collider col in collidersInRange) {
damageByGrenadeExplosion = col.GetComponent<Health> ();
if (damageByGrenadeExplosion != null)
damageByGrenadeExplosion.Damage (exploDamage); 

All the above code does is take in to account all the colliders in the range of the grenade. Then it takes the health script attached to each NPC/object and keep it in the variable: damageByGrenadeExplosion. Then with that variable we check if it damaged, if it did we apply the damage the grenade does to the health script in each NPC/Object.

Finally, destroy the prefab and the instantiate particle to save on memory. Now, its interesting to note, that the the float variables are very important. For the destroy gmeObject the float value is necessary to allow the sound clip to fully play, lowering the value will cut the sound clip. As for the destroy insta the float value dictates how long the particle will be allowed to bloom. Lowering will cut the particle animation short, the longer it is the more particle animations will play.
Destroy (gameObject, 5.50f);
Destroy (insta, 0.4f);

Now make a new script and call it Grenade:

The variables here are simple. We need one to keep track of how many grenades the player can have. How much force the player has behind their throw. The other two are used as a point where the grenade prefab will be spawned from, and a variable for the grenade prefab. And the final is a variable for a custom font we will be using for the GUI.

In the Update() we first check to see if the player pressed the G button: if(Input.GetKeyDown(KeyCode.G)) The a sub if condition to see if we have any grenades to throw: if(GAmount > 0)

Next we have to create the prefab in the game world, so we make a temp Rigidbody to hold the grenade instantiate the prefab at the position of the player and their rotation:
Rigidbody spawnG = (Rigidbody)Instantiate(grenade, player.position, player.rotation);

Once the grenade has been spawned we need to make it more realistic, we will add torque so the grenade rolls when it hits the ground:

Finally we have to move the grenade, so we call transform.forward to push it and multiply the speed based on the force variable representing the players throw force.
spawnG.AddForce(transform.forward * force);

Then we subtract a grenade.

The OnGUI() is next. First we have to make a new GUIStyle. I called my TinkerFont. Now we have to link the TinkerFont to the variable we declared earlier: TinkerFont.font=Tinker; The next few codes are straight forward, setting the size of the font, and the color.
The last line calls the GUI.Label to draw the amount of grenades; by calling the method Value(int), you have in the position specified.

The code above is self explanatory. We pass a value into the Value() method, and convert it to a string.

Now finally, the GrenadeExplosion script attach to your grenade prefab. For the Grenade script you first have to make an empty Game Object, position the empty game object to where you want it on your player character and parent the empty Game Object to your player object and now attach the script to your empty Game Object.

Next few tutorials will be: Projectile weapons, GUI Crosshairs, basic AI.
Below are screen shots of the complete source code:


EDIT-2: Decided to upload this to the Drive:

No comments:

Post a Comment