Contenido

Los tanques

Creación del tanque

  • Desde dentro de la carpeta Models de la Project Window, arrastra el modelo Tank a la Hierarchy Window.
  • En la Inspector Window del Tank, escoge la Layer Players y, cuando te pregunte si quieres que se lo aplique a todos sus elementos hijos, pulsa en No, this object only.
  • Añade un Rigidbody Component al Tank.
  • Expande Constraints y selecciona Freeze position para el eje Y y Freeze rotation para los ejes X y Z.
  • Añade un Box Collider Component al Tank.
  • Cambia el Center a XYZ 0, 0.85, 0 y el Size a XYZ 1.5, 1.7, 1.6.
  • Añade un Audio Source Component al Tank.
  • En AudioClip, haz clic en el circulo selector y selecciona EngineIdle de la lista.
  • Activa la opción Loop.
  • Añade otro Audio Source Component al Tank.
  • Desactiva la opción Play on Awake (reproducir al arrancar).
  • Selecciona la carpeta Prefabs de Project Window y arrastra el Tank de la Hierarchy Window a dicha carpeta (para guardar los cambios en el Prefab).
  • Guarda la escena

Movimiento del tanque

Las acciones a realizar son:
  • Capturar la entrada
  • Configurar el audio
  • Configurar el movimiento adelante y atrás
  • Configurar el giro
Para ello:
  • Desde dentro de la carpeta Prefabs de la Project window, arrastra el prefab DustTrail al Tank de la Hierarchy window.
  • Duplica ese DustTrail.
  • Renombra uno como LeftDustTrail y cambia la Position a XYZ -0.5, 0, -0.75.
  • Renombra el otro como RightDustTrail y cambia la Position a XYZ 0.5, 0, -0.75.
  • Desde dentro de la carpeta Scripts/Tank de la Project Window, arrastra el archivo TankMovement al Tank de la Hierarchy window
  • Abre el archivo TankMovement, y modifica el código para que sea similar al expuesto más abajo (e intenta comprenderlo fijándote en los comentarios)
  • En la Inspector window de Tank, arrastra el primer Audio Source a la casilla del Tank Movement Script correspondiente a Movement Audio.
  • Para la variable Engine Idling del Tank Movement Script, haz clic en el circulo selector y escoge EngineIdle.
  • Para la variable Engine Driving del Tank Movement Script, haz clic en el circulo selector y escoge EngineDriving.
  • El resultado debe ser similar al de la figura siguiente.
  • En la parte superior de la Inspector window, haz clic en Apply para aplicar los cambios al Prefab.
  • Guarda la escena y prueba a mover el tanque pulsando Play y usando los controles WASD.

using UnityEngine;

public class TankMovement : MonoBehaviour
{
    public int m_PlayerNumber = 1;              // Utilizado para identificar qué tanque es de cada jugador.  Configurado por el tank's manager.
    public float m_Speed = 12f;                 // Rapidez con la que el tanque se mueve alante y atrás.
    public float m_TurnSpeed = 180f;            // Rapidez de giro del tanque en grados por segundo.
    public AudioSource m_MovementAudio;         // Referencia al audio del motor del tanque (diferente del de disparo).
    public AudioClip m_EngineIdling;            // Audio a reproducir cuando el tanque no se mueve.
    public AudioClip m_EngineDriving;           // Audio a reproducir cuando el tanque se está moviendo.
    public float m_PitchRange = 0.2f;           // Cantidad de variación de afinación del audio del motor (para que sea más real).


    private string m_MovementAxisName;          // Nombre del eje para moerse alante y atrás.
    private string m_TurnAxisName;              // Nombre del eje para girar.
    private Rigidbody m_Rigidbody;              // Referencia del componente para mover el tanque.
    private float m_MovementInputValue;         // Valor actual de entrada para el movimiento.
    private float m_TurnInputValue;             // Valor actual de entrada para el giro.
    private float m_OriginalPitch;              // Valor del pitch de la fuente de audio al inicio.


    private void Awake ()
    {
        m_Rigidbody = GetComponent ();
    }


    private void OnEnable ()
    {
        // Al arrancar/habilitar el tanque, deshabilitamos la kinemática del tanque para que se pueda mover.
        m_Rigidbody.isKinematic = false;

        // Reseteamos los valores de entrada.
        m_MovementInputValue = 0f;
        m_TurnInputValue = 0f;
    }


    private void OnDisable ()
    {
        // Al parar/deshabilitar el tanque, habilitamos la kinemática del tanque para que se pare.
        m_Rigidbody.isKinematic = true;
    }


    private void Start ()
    {
        // NOmbres de los ejes según el número de jugador.
        m_MovementAxisName = "Vertical" + m_PlayerNumber;
        m_TurnAxisName = "Horizontal" + m_PlayerNumber;

        // Almaceno la afinación original del audio del motor.
        m_OriginalPitch = m_MovementAudio.pitch;
    }


    private void Update ()
    {
        // Almaceno los valores de entrada.
        m_MovementInputValue = Input.GetAxis (m_MovementAxisName);
        m_TurnInputValue = Input.GetAxis (m_TurnAxisName);

        //Llamo a la función que gestiona el audio del motor
        EngineAudio ();
    }


    private void EngineAudio ()
    {
        // Si no hay entrada, es que está quieto...
        if (Mathf.Abs (m_MovementInputValue) < 0.1f && Mathf.Abs (m_TurnInputValue) < 0.1f)
        {
            // ... y si estaba reproduciendo el audio de moverse...
            if (m_MovementAudio.clip == m_EngineDriving)
            {
                // ... cambio el audio al de estar parado y lo reproduzco.
                m_MovementAudio.clip = m_EngineIdling;
                m_MovementAudio.pitch = Random.Range (m_OriginalPitch - m_PitchRange, m_OriginalPitch + m_PitchRange);
                m_MovementAudio.Play ();
            }
        }
        else
        {
            //Si hay entrada es que se está moviendo. Si estaba reproduciendo eld e estar parado...
            if (m_MovementAudio.clip == m_EngineIdling)
            {
                // ... cambio el audio al de moverse y lo reproduzco.
                m_MovementAudio.clip = m_EngineDriving;
                m_MovementAudio.pitch = Random.Range(m_OriginalPitch - m_PitchRange, m_OriginalPitch + m_PitchRange);
                m_MovementAudio.Play();
            }
        }
    }


    private void FixedUpdate ()
    {
        // Ajusto la posición y rotación.
        Move ();
        Turn ();
    }


    private void Move ()
    {
        // Creo un vector en la dirección en la que apunta el tanque, con una magnitud basada en la entrada, la velocidad y el tiempo entre frames.
        Vector3 movement = transform.forward * m_MovementInputValue * m_Speed * Time.deltaTime;

        // Aplico ese vector de movimiento al rigidbody del tanque.
        m_Rigidbody.MovePosition(m_Rigidbody.position + movement);
    }


    private void Turn ()
    {
        // Calculo el número de grados de rotación basandome en la entrada, la velocidad y el tiempo entre frames.
        float turn = m_TurnInputValue * m_TurnSpeed * Time.deltaTime;

        // Convierto ese número en una rotación en el eje Y.
        Quaternion turnRotation = Quaternion.Euler (0f, turn, 0f);

        // AAplico esa rotación al rigidbody del tanque.
        m_Rigidbody.MoveRotation (m_Rigidbody.rotation * turnRotation);
    }
}