Des composants abstraits
Fait partie de la section Architecture de jeu dans Unity du Journey Unity de Coddy. Leçon 3 sur 50.
Certaines classes de base décrivent un type de chose qui n’existe jamais par elle-même. Chaque arme tire, mais une arme qui n’est ni un pistolet ni un fusil à pompe n’a aucun moyen de tirer. Marquez une telle classe comme abstract, et déclarez chaque étape que ses sous-classes doivent écrire comme méthode abstraite, sans corps :
public abstract class Weapon : MonoBehaviour
{
public int shots;
public void Pull()
{
shots++;
Fire();
}
protected abstract void Fire();
}public class Shotgun : Weapon
{
public GameObject pelletPrefab;
protected override void Fire()
{
for (int i = -1; i <= 1; i++)
{
Instantiate(pelletPrefab, transform.position + transform.right * i * 0.3f, transform.rotation);
}
}
}Une sous-classe qui n’écrit pas Fire ne compile pas : CS0534, 'Pistol' does not implement inherited abstract member 'Weapon.Fire()'. Unity refuse également d’ajouter un script abstrait à un objet. Faites glisser Weapon sur un objet et le message suivant s’affiche : Can't add script behaviour 'Weapon'. The script class can't be abstract!, car Unity ne pourrait pas créer une arme sans Fire.
Les autres scripts fonctionnent toujours avec le type de base. GetComponent<Weapon>() renvoie la sous-classe présente sur l’objet, et Pull() exécute le Fire de cette sous-classe :
// Player.cs
private Weapon weapon;
void Start()
{
weapon = GetComponent<Weapon>();
}
void Update()
{
if (Mouse.current.leftButton.wasPressedThisFrame)
{
weapon.Pull();
}
}Remplacez le composant Shotgun par un Pistol, et le script Player reste le même.
Défi
FacileLa tour du sorcier foudroie les monstres dans le champ. Monster.cs contient ce que tous les monstres ont en commun : hp (3) et Zap(), qui retire 1 hp, détruit le monstre à 0 et appelle sinon React(). Slime.cs réagit en rétrécissant. Imp.cs n’a aucune réaction, et Monster lui fournit un React vide : rien ne signale donc son absence.
- Rends Monster abstraite et React une méthode abstraite, afin qu’un monstre qui ne précise pas comment il réagit ne compile pas. Le compilateur indique alors Imp.
- Écris le React de Imp : il saute de 2 unités en arrière, à l’opposé de la tour (le long de +z).
- Dans Tower.cs, lorsque la barre d’espace est enfoncée, récupère le composant Monster de chaque objet étiqueté Monster, quel que soit son type, et appelle
Zap().
Appuie sur Play et foudroie les monstres, puis sur Check.
Essayez vous-même
using UnityEngine;
// Ce que tous les monstres ont en commun.
public class Monster : MonoBehaviour
{
public int hp = 3;
public void Zap()
{
hp--;
if (hp <= 0)
{
Destroy(gameObject);
}
else
{
React();
}
}
// Comment ce type de monstre réagit à une décharge à laquelle il survit.
protected virtual void React()
{
}
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Architecture de jeu dans Unity
1Des composants, pas des hiérarchies
Des composants simplesUn script de base pour les ennemisDes composants abstraitsDes composants qui fonctionnent ensembleRécapitulatif : tourelle modulaire4Données sérialisées
Classes sérialisablesListes dans l’inspecteurÉnumérations dans l’inspecteurRécapitulatif : table de butin7Machines à états
Les états sous forme de classesUne machine à étatsTransitionsLes cerveaux des ennemisRécapitulatif : états d’une porte10Projet : Survivant de l’arène
Le hérosTypes d’ennemis2Interfaces dans Unity
IDamageableInterfaces et TryGetComponentGetComponentsRécapitulatif : touche d’interaction5ScriptableObjects
Assets de donnéesStatistiques des armesParamètres partagésLes vagues sous forme de donnéesRécapitulatif : base de données d’objets