Project
Tanks
Creating and Firing Shells
Tutorial
Intermediate
1 Hour5 Mins
Unity Technologies
Overview
Overview
You have completed 0% of this Tutorial.
1.
Shell Creation
2.
Firing Shells
Summary
This section of the Unity Tanks project demonstrates how to create the shell projectiles and implement the firing of shells along with their explosion effects.
Language
English
Recommended Unity Versions
5.2
Tutorial Materials
1.
Shell Creation
Phase 5 teaches you how to create a Shell for the tank, creating a radius for explosion.

ShellExplosion Script

using UnityEngine; public class ShellExplosion : MonoBehaviour { public LayerMask m_TankMask; // Used to filter what the explosion affects, this should be set to "Players". public ParticleSystem m_ExplosionParticles; // Reference to the particles that will play on explosion. public AudioSource m_ExplosionAudio; // Reference to the audio that will play on explosion. public float m_MaxDamage = 100f; // The amount of damage done if the explosion is centred on a tank. public float m_ExplosionForce = 1000f; // The amount of force added to a tank at the centre of the explosion. public float m_MaxLifeTime = 2f; // The time in seconds before the shell is removed. public float m_ExplosionRadius = 5f; // The maximum distance away from the explosion tanks can be and are still affected. private void Start () { // If it isn't destroyed by then, destroy the shell after it's lifetime. Destroy (gameObject, m_MaxLifeTime); } private void OnTriggerEnter (Collider other) { // Collect all the colliders in a sphere from the shell's current position to a radius of the explosion radius. Collider[] colliders = Physics.OverlapSphere (transform.position, m_ExplosionRadius, m_TankMask); // Go through all the colliders... for (int i = 0; i < colliders.Length; i++) { // ... and find their rigidbody. Rigidbody targetRigidbody = colliders[i].GetComponent<Rigidbody> (); // If they don't have a rigidbody, go on to the next collider. if (!targetRigidbody) continue; // Add an explosion force. targetRigidbody.AddExplosionForce (m_ExplosionForce, transform.position, m_ExplosionRadius); // Find the TankHealth script associated with the rigidbody. TankHealth targetHealth = targetRigidbody.GetComponent<TankHealth> (); // If there is no TankHealth script attached to the gameobject, go on to the next collider. if (!targetHealth) continue; // Calculate the amount of damage the target should take based on it's distance from the shell. float damage = CalculateDamage (targetRigidbody.position); // Deal this damage to the tank. targetHealth.TakeDamage (damage); } // Unparent the particles from the shell. m_ExplosionParticles.transform.parent = null; // Play the particle system. m_ExplosionParticles.Play(); // Play the explosion sound effect. m_ExplosionAudio.Play(); // Once the particles have finished, destroy the gameobject they are on. Destroy (m_ExplosionParticles.gameObject, m_ExplosionParticles.duration); // Destroy the shell. Destroy (gameObject); } private float CalculateDamage (Vector3 targetPosition) { // Create a vector from the shell to the target. Vector3 explosionToTarget = targetPosition - transform.position; // Calculate the distance from the shell to the target. float explosionDistance = explosionToTarget.magnitude; // Calculate the proportion of the maximum distance (the explosionRadius) the target is away. float relativeDistance = (m_ExplosionRadius - explosionDistance) / m_ExplosionRadius; // Calculate damage as this proportion of the maximum possible damage. float damage = relativeDistance * m_MaxDamage; // Make sure that the minimum damage is always 0. damage = Mathf.Max (0f, damage); return damage; } }

2.
Firing Shells
Phase 6 teaches you how to fire projectiles, and make a UI & Sound fx to accompany the mechanic.

TankShooting Script

using UnityEngine; using UnityEngine.UI; public class TankShooting : MonoBehaviour { public int m_PlayerNumber = 1; // Used to identify the different players. public Rigidbody m_Shell; // Prefab of the shell. public Transform m_FireTransform; // A child of the tank where the shells are spawned. public Slider m_AimSlider; // A child of the tank that displays the current launch force. public AudioSource m_ShootingAudio; // Reference to the audio source used to play the shooting audio. NB: different to the movement audio source. public AudioClip m_ChargingClip; // Audio that plays when each shot is charging up. public AudioClip m_FireClip; // Audio that plays when each shot is fired. public float m_MinLaunchForce = 15f; // The force given to the shell if the fire button is not held. public float m_MaxLaunchForce = 30f; // The force given to the shell if the fire button is held for the max charge time. public float m_MaxChargeTime = 0.75f; // How long the shell can charge for before it is fired at max force. private string m_FireButton; // The input axis that is used for launching shells. private float m_CurrentLaunchForce; // The force that will be given to the shell when the fire button is released. private float m_ChargeSpeed; // How fast the launch force increases, based on the max charge time. private bool m_Fired; // Whether or not the shell has been launched with this button press. private void OnEnable() { // When the tank is turned on, reset the launch force and the UI m_CurrentLaunchForce = m_MinLaunchForce; m_AimSlider.value = m_MinLaunchForce; } private void Start () { // The fire axis is based on the player number. m_FireButton = "Fire" + m_PlayerNumber; // The rate that the launch force charges up is the range of possible forces by the max charge time. m_ChargeSpeed = (m_MaxLaunchForce - m_MinLaunchForce) / m_MaxChargeTime; } private void Update () { // The slider should have a default value of the minimum launch force. m_AimSlider.value = m_MinLaunchForce; // If the max force has been exceeded and the shell hasn't yet been launched... if (m_CurrentLaunchForce >= m_MaxLaunchForce && !m_Fired) { // ... use the max force and launch the shell. m_CurrentLaunchForce = m_MaxLaunchForce; Fire (); } // Otherwise, if the fire button has just started being pressed... else if (Input.GetButtonDown (m_FireButton)) { // ... reset the fired flag and reset the launch force. m_Fired = false; m_CurrentLaunchForce = m_MinLaunchForce; // Change the clip to the charging clip and start it playing. m_ShootingAudio.clip = m_ChargingClip; m_ShootingAudio.Play (); } // Otherwise, if the fire button is being held and the shell hasn't been launched yet... else if (Input.GetButton (m_FireButton) && !m_Fired) { // Increment the launch force and update the slider. m_CurrentLaunchForce += m_ChargeSpeed * Time.deltaTime; m_AimSlider.value = m_CurrentLaunchForce; } // Otherwise, if the fire button is released and the shell hasn't been launched yet... else if (Input.GetButtonUp (m_FireButton) && !m_Fired) { // ... launch the shell. Fire (); } } private void Fire () { // Set the fired flag so only Fire is only called once. m_Fired = true; // Create an instance of the shell and store a reference to it's rigidbody. Rigidbody shellInstance = Instantiate (m_Shell, m_FireTransform.position, m_FireTransform.rotation) as Rigidbody; // Set the shell's velocity to the launch force in the fire position's forward direction. shellInstance.velocity = m_CurrentLaunchForce * m_FireTransform.forward; ; // Change the clip to the firing clip and play it. m_ShootingAudio.clip = m_FireClip; m_ShootingAudio.Play (); // Reset the launch force. This is a precaution in case of missing button events. m_CurrentLaunchForce = m_MinLaunchForce; } }

Woohoo! You nailed this tutorial.
Continue rocking your Tanks project.
Next Step:
Game Managers
Tutorial
Intermediate
55 Mins
Unity Technologies
Part of: