Contenido

La salud

Introducción

En esta entrada nos centraremos en crear unos medidores de vida o salud para nuestros tanques. Pero antes de eso, debemos asegurarnos de que el selector de transformación (transform toggle) debe estar configurado a Pivot.
Fuente: Unity
Según el Manual de Unity: Los Gizmo Display Toggles son usados para definir la ubicación de cualquier Transform Gizmo. Para la Posición:
  • Center posicionará el Gizmo en el centro de los limites dictados del objeto.
  • Pivot posicionará el Gizmo en el punto de pivote actual de un Mesh (malla a base de triángulos organizados en un espacio 3D para crear la impresión de un objeto sólido).
Para la Rotación:
  • Local mantendrá la rotación del Gizmo de forma relativa a la del objeto.
  • Global anclará el Gizmo a la orientación espacial del mundo.

Elementos medidores de vida

  • Crea un nuevo GameObject > UI > Slider y selecciona el EventSystem creado
  • En el Standalone Input Module que aparece en la Inspector window, cambia Horizontal Axis a HorizontalUI y Vertical Axis a VerticalUI.
  • Selecciona el Canvas creado y cambia Reference Pixels per Unit a 1 y Render Mode a World Space.
  • En la Hierarchy window, arrastra el Canvas al Tank para que sea su hijo.
  • Selecciona el Canvas y en RectTransform cambia Position a 0, 0.1, 0, Width y Height a 3.5 y Rotation a 90, 0, 0.
  • Expande el Canvas y todos sus hijos haciendo Alt + click en el triángulo.
  • Elimina el HandleSlideArea.
  • Selecciona Slider, Background, Fill Area y Fill con Ctrl + click o Cmd + click.
  • Haz clic en los Anchor Presets y haz Alt + click en el de abajo a la derecha para que haga stretch (estire) a todos los objetos en el Canvas.
  • Selecciona el Slider y renómbralo a HealthSlider
  • Deselecciona Interactable, cambia Transition a None y Max Value y Value a 100.
  • Selecciona Background y en Image Component usa el círculo selector para cambiar Source Image a HealthWheel.
  • Haz clic en Color para cambiar su alpha (A) a 80.
  • Selecciona Fill y en Image Component usa el círculo selector para cambiar Source Image a HealthWheel.
  • Haz clic en Color para cambiar su alpha (A) a 150.
  • Cambia su Image Type a Filled, el Fill Origin a Left y deselecciona Clockwise.
  • Guarda la escena.

Script de control para el slider

Selecciona el script UIDIrectionControl en la carpeta Scripts > UI y arrástralo al HealthSlider. Selecciona el Tank y haz clic en Apply en la parte superior de la Inspector window para guardar el prefab. El código del script debe ser similar a este:

using UnityEngine;

public class UIDirectionControl : MonoBehaviour
{
    //Esta clase se usa para asegurarnos de que los elementos del espacio UI
    //se posicionan correctamente


    public bool m_UseRelativeRotation = true;


    private Quaternion m_RelativeRotation;


    private void Start()
    {
        m_RelativeRotation = transform.parent.localRotation;
    }


    private void Update()
    {
        if (m_UseRelativeRotation)
            transform.rotation = m_RelativeRotation;
    }
}

Script de control de salud para el tanque

Las acciones a realizar son:
  • Configurar el daño del tanque
  • Actualizar la UI en función de la salud del tanque
  • Desactivar el tanque
Para ello:
  • Desde la carpeta Prefabs, arrastra TankExplosion a la Hierarchy window.
  • Añádele un AudioSource, asigna el AudioClip TankExplosion y deselecciona Play On Awake.
  • Haz clic en Apply del TankExplosion para guardar el Prefab y borra TankExplosion de la Hierarchy window (lo añadiremos después con un script).
  • Desde la carpeta Scripts > Tank, arrastra TankHealth al Tank y ábrelo.
  • El código debería ser como el mostrado a continuación, y deberías fijarte en los comentarios e intentar entenderlo:

using UnityEngine;
using UnityEngine.UI;

public class TankHealth : MonoBehaviour
{
    public float m_StartingHealth = 100f; //Cantidad de salud con la que empeiza el tanque
    public Slider m_Slider; //Slider que representa la salud del tanque
    public Image m_FillImage; //COmponente de imagen del slider
    public Color m_FullHealthColor = Color.green;  //Color del slider con salud completa (verde)
    public Color m_ZeroHealthColor = Color.red; //Color del slider con salud vacía (rojo)
    public GameObject m_ExplosionPrefab; //Prefab que instanciamos al inicio y usamos cuando el tanque se muere


    private AudioSource m_ExplosionAudio; //La fuenta de audio a reporudcir cuando el tanque explota
    private ParticleSystem m_ExplosionParticles; //Sistema de partículas que se reproducen al destruir el tanque
    private float m_CurrentHealth; //Variable para almacenar la salud del tanque
    private bool m_Dead; //Variable para comprobar si el tanque tiene salud


    private void Awake()
    {
        //Instanciamos el prefab de la explosión
        m_ExplosionParticles = Instantiate(m_ExplosionPrefab).GetComponent<ParticleSystem>();

        //Refrencia de la fuente de audio para la explosión
        m_ExplosionAudio = m_ExplosionParticles.GetComponent<AudioSource>();

        //Deshabilitimas el sistema de partículas de la explosión (para activarlo cuando explote)
        m_ExplosionParticles.gameObject.SetActive(false);
    }


    private void OnEnable()
    {
        //Al habilitar el tanque, reseteamos la salud y el booleano de si está muerto o no
        m_CurrentHealth = m_StartingHealth;
        m_Dead = false;

        //Actualizamos el slider de salud (valor y color)
        SetHealthUI();
    }


    public void TakeDamage(float amount)
    {
        // Reducimos la salud según la cantidad de daño recibida.
        m_CurrentHealth -= amount;

        // Actualizamos el slider de salud con esos valores
        SetHealthUI ();

        // Si la salud es menor que 0 y aún no lo he explotado, llamo al método OnDeath (al morir).
        if (m_CurrentHealth <= 0f && !m_Dead)
        {
            OnDeath ();
        }
    }


    private void SetHealthUI()
    {
        // Ajusto el valor del slider.
        m_Slider.value = m_CurrentHealth;

        // Creo un color para el slider entre verde y rojo en función del porcentaje de salud
        m_FillImage.color = Color.Lerp (m_ZeroHealthColor, m_FullHealthColor, m_CurrentHealth / m_StartingHealth);
    }


    private void OnDeath()
    {
        // Configuro el booleano a true para asegurarme de que explota solo una vez.
        m_Dead = true;

        // Coloco el prefab de explosión en la posición actual del tanque y lo activo.
        m_ExplosionParticles.transform.position = transform.position;
        m_ExplosionParticles.gameObject.SetActive (true);

        // Reproduzco el sistema de partículas del tanque explotando.
        m_ExplosionParticles.Play ();

        // Reproduzco el audio del tanque explotando.
        m_ExplosionAudio.Play();

        // Desactivo el tanque.
        gameObject.SetActive (false);
    }
}
Es el momento de asignar los objetos a las variables públicas de nuestro script:
  • Selecciona el Tank.
  • Arrastra el HealthSlider a la variable HealthSlider del script
  • Haz lo mismo con Fill.
  • Arrastra el prefab TankExplosion (desde la carpeta Prefabs) a la variable Explosion Prefab del script.
  • Haz clic en Apply de la Inspector window para guardar los cambios al prefab Tank.
  • Guarda la escena.
Si ahora ejecutas el juego, deberías ver siempre un círculo verde alrededor del tanque que nos indicará la salud del mismo.