Imaginons un jeu de type FPS (First Person Shooter) où l’on peut provoquer des dégâts en tirant sur un ennemi mais aussi sur certains objets, le décors ou encore sur un véhicule, nous pourrions faire comme ceci :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
private void Tirer() { RaycastHit hit; if (Physics.Raycast(_camera.transform.position, _camera.transform.forward, out hit, _distance) { Vitre vitre = hit.collider.gameObject.GetComponent(); if (vitre != null) { vitre.Endommager(10); return; } Caisse caisse = hit.collider.gameObject.GetComponent(); if (caisse != null) { caisse.Endommager(10); return; } Voiture voiture = hit.collider.gameObject.GetComponent(); if (voiture != null) { voiture.Endommager(10); return; } Ennemi ennemi = hit.collider.gameObject.GetComponent(); if (ennemi != null) { ennemi.Endommager(10); return; } BarilExplosif barilExplosif = hit.collider.gameObject.GetComponent(); if (barilExplosif != null) { barilExplosif.Endommager(10); return; } } } |
Cette méthode va fonctionner mais elle contraignante, peu optimisée et assez « moche » il faut l’avouer.
Essayons de simplifier en essayant la méthode SendMessage() :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
private void Tirer() { RaycastHit hit; if (Physics.Raycast(_camera.transform.position, _camera.transform.forward, out hit, _distance) { var component = hit.collider.gameObject.GetComponent(typeof(Vitre)) ?? hit.collider.gameObject.GetComponent(typeof(Caisse)) ?? hit.collider.gameObject.GetComponent(typeof(Voiture)) ?? hit.collider.gameObject.GetComponent(typeof(Ennemi)) ?? hit.collider.gameObject.GetComponent(typeof(BarilExplosif)); if (component != null) { component.SendMessage("Endommager", 10); } } } |
C’est plus propre mais l’appel de la méthode SendMessage() est coûteuse en ressource (et c’est dommage de l’utiliser pour une méthode aussi simple que d’envoyer une variable) et en plus on devra mettre à jour ce script autant de fois que l’on aura de classe avec la méthode Endommager().
Une des solution à ce problème serait d’utiliser une interface pour toutes les classes qui pourront être endommagées par la méthode Tirer().
Créons donc l’interface avec la méthode Endommager(), la propriété PointsDeVie et appellons la IEndommageable.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public interface IEndommageable { /// /// Les points de vie de l'objet, à zéro l'objet est détruit /// int PointsDeVie { get; } /// /// Permet de retirer le nombre passé en paramètre à la propriété PointsDeVie /// /// void Endommager(int pDégât); } |
Une fois l’interface créée, nous allons l’implémentée dans la classe d’un objet qui peut être endommagé en y ajoutant la variable privée _pointsDeVie et une condition dans la méthode Endommager() qui détruira le gameobjet au moment où les points de vie arrivent à zéro.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public class Caisse : MonoBehaviour, IEndommageable { private int _pointsDeVie = 100; public int PointsDeVie { get { return _pointsDeVie; } } public void Endommager(int pDégât) { _pointsDeVie -= pDégât; if (_pointsDeVie <= 0) { Destroy(gameObject); } } } |
Il ne reste plus qu’à modifier notre méthode Tirer() pour prendre en compte notre nouvelle interface.
1 2 3 4 5 6 7 8 9 10 11 12 |
private void Tirer() { RaycastHit hit; if (Physics.Raycast(_camera.transform.position, _camera.transform.forward, out hit, _distance) { IEndommageable objetEndommageable = hit.collider.gameObject.GetComponent(); if (objetEndommageable != null) { objetEndommageable.Endommager(35); } } } |
Et voilà, pour endommager un nouvelle objet, il suffira d’ajouter et implémenter l’interface IEndommageable et il pourra être endommagé et détruit très facilement.
My partner and I stumbled over here from a different page and thought I may as well check things out.
I like what I see so now i’m following you.
Look forward to looking over your web page for a second time.
I do accept as true with all of the concepts you’ve offered on your post.
They’re really convincing and will definitely work. Nonetheless, the posts
are too quick for novices. May just you please extend
them a little from subsequent time? Thanks for the post.