Unity - Tanks

Missile

L'auteur

Site personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Introduction

Voici le cinquième épisode de la formation donnée au cours du Unite 2015 à Boston durant laquelle vous allez apprendre à faire un jeu où deux tanks s'affrontent.
Vous pouvez retrouver les autres épisodes de cette série dans le sommaire dédié.

II. Vidéo


Unity - Tanks ! - Missile


III. Résumé

Dans cette cinquième vidéo, vous allez suivre la création des missiles et leur interaction avec le reste du jeu.

III-A. Création du missile

III-A-1. Description

Le missile sera évidemment tiré à partir d'un tank. Lorsque celui-ci touche le sol, il explose, inflige des dégâts dans une zone donnée, génère des particules et suivant la distance avec le tank, repousse le tank touché.

III-A-2. Implémentation

Le missile est implémenté grâce aux composants suivants :

  • un modèle 3D ;
  • une capsule englobante ;
  • un rigid body ;
  • une lumière ;
  • un script.

Premièrement, prenez le modèle 3D nommé « Shell » et insérez-le dans la hiérarchie. Ajoutez-lui un « CapsuleCollider ». Dans ce jeu, un missile n'a pas besoin de rebondir ou de respecter une quelconque collision. La seule chose utile est que l'on sache lorsque le missile rentre en contact avec un objet. Pour cela, il est nécessaire de cocher la propriété « Is Trigger ». Ainsi, le missile n'agit pas sur la physique du jeu, mais provoque l'appel à une fonction informant que celui-ci est rentré en contact. Finalement, vous devez changer son centre à (0, 0, 0.2), son radius 0.15, sa taille à 0.55 et comme, pour notre cas, la direction est incorrecte par défaut, changer la direction pour l'orienter suivant l'axe Z.
Ensuite, vous devez ajouter un RigidBody.

Dans le dossier des préfabriqués, vous pouvez trouver un élément appelé « ShellExplosion » à définir comme enfant de votre missile. Celui-ci consiste en un système de particules. Comme pour l'explosion du tank, vous devez lui ajouter une source audio et définir le son avec le clip « ShellExplosion », puis décocher le « Play On Awake ».

Ensuite, ajoutez une lumière.

Finalement, prenez le script « Shell Explosion » et placez-le comme composant au missile.

III-B. Script du missile

Un script est associé au missile afin de programmer le comportement lors de l'explosion du missile. En effet, plusieurs choses arrivent lors de celle-ci :

  • un système de particules est créé ;
  • un son est joué pour accompagner l'effet visuel de l'explosion ;
  • les objets alentour sont expulsés ;
  • des dégâts sont infligés aux tanks alentour.

III-B-1. Script

 
Sélectionnez
using UnityEngine;

public class ShellExplosion : MonoBehaviour
{
    public LayerMask m_TankMask;                        // Utilisé pour filtrer ce que l'explosion impacte, cela devrait être défini à « Players ».
    public ParticleSystem m_ExplosionParticles;         // Référence le système de particules joué lors de l'explosion.
    public AudioSource m_ExplosionAudio;                // Référence le son joué lors de l'explosion.
    public float m_MaxDamage = 100f;                    // Les dégâts infligés lorsque l'explosion est sur le tank.
    public float m_ExplosionForce = 1000f;              // La force de l'onde de choc à appliquer sur le tank.
    public float m_MaxLifeTime = 2f;                    // Le temps en secondes avant que le missile soit retiré.
    public float m_ExplosionRadius = 5f;                // La distance maximale d'effet de l'onde de choc.


    private void Start ()
    {
        // Si l'objet n'est pas détruit entretemps, détruit le missile après sa durée de vie.
        Destroy (gameObject, m_MaxLifeTime);
    }


    private void OnTriggerEnter (Collider other)
    {
        // Récupère tous les objets ayant une collision dans la sphère entourant le missile.
        Collider[] colliders = Physics.OverlapSphere (transform.position, m_ExplosionRadius, m_TankMask);

        // Parcourt tous les objets...
        for (int i = 0; i < colliders.Length; i++)
        {
            // ... et récupère le « RigidBody ».
            Rigidbody targetRigidbody = colliders[i].GetComponent<Rigidbody> ();

            // S'il n'y a pas de « RigidBody », passe à l'objet suivant.
            if (!targetRigidbody)
                continue;

            // Ajoute la force de l'explosion.
            targetRigidbody.AddExplosionForce (m_ExplosionForce, transform.position, m_ExplosionRadius);

            // Trouve le script de gestion de vie du tank associé à ce « RigidBody ».
            TankHealth targetHealth = targetRigidbody.GetComponent<TankHealth> ();

            // S'il n'y a pas de script à cet objet, passe au suivant.
            if (!targetHealth)
                continue;

            // Calcule les dégâts infligés suivant la distance entre l'objet et le missile.
            float damage = CalculateDamage (targetRigidbody.position);

            // Répercute ces dégâts sur le tank.
            targetHealth.TakeDamage (damage);
        }

        // Détache le système de particules du missile.
        m_ExplosionParticles.transform.parent = null;

        // Joue le système de particules.
        m_ExplosionParticles.Play();

        // Joue le son d'explosion.
        m_ExplosionAudio.Play();

        // Une fois le système de particules terminé, détruit l'objet associé.
        Destroy (m_ExplosionParticles.gameObject, m_ExplosionParticles.duration);

        // Détruit le missile.
        Destroy (gameObject);
    }


    private float CalculateDamage (Vector3 targetPosition)
    {
        // Crée un vecteur entre le missile et la cible.
        Vector3 explosionToTarget = targetPosition - transform.position;

        // Calcule la distance entre le missile et la cible.
        float explosionDistance = explosionToTarget.magnitude;

        // Calcule la proportion par rapport à la distance maximale et la distance actuelle.
        float relativeDistance = (m_ExplosionRadius - explosionDistance) / m_ExplosionRadius;

        // Calcule les dégâts infligés suivant la proportion.
        float damage = relativeDistance * m_MaxDamage;

        // S'assure que le minimum de dégâts infligés est toujours 0.
        damage = Mathf.Max (0f, damage);

        return damage;
    }
}

III-B-2. Lors d'une collision

Lorsque le missile entre en collision avec un objet, la fonction OnTriggerEnter() est automatiquement appelée par Unity. Dans celle-ci, il est nécessaire de vérifier tous les objets qui seront impactés par le missile grâce à la fonction OverlapSphere(). En réalité et pour des raisons de performances, tous les objets ne seront pas récupérés grâce à l'utilisation d'un masque. Seuls les objets dans la catégorie appropriée seront retournés par la fonction. Ensuite, pour tous les objets, une force est appliquée afin de simuler l'onde de choc et pour les tanks, de l'énergie est retirée. Les dégâts infligés ainsi que le recul provoqué par l'onde de choc sont calculés par rapport à la distance entre l'objet et le missile.

III-B-3. Finalisation

Pour finir, définissez les variables exposées dans l'inspecteur. Mettez à jour le préfabriqué du missile et testez ! Vous pouvez supprimer le missile, celui-ci sera créé dynamiquement par la suite.

IV. Ressources

Vous pouvez télécharger le diaporama de la présentation.

Vous pouvez télécharger les ressources pour ce projet sur l'Asset Store de Unity.

V. Commenter

Vous pouvez commenter et donner vos avis dans la discussion associée sur le forum.

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Copyright © 2016 Unity Technologies. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.