Fonctions utilitaires génériques
Fait partie de la section Architecture de jeu dans Unity du Journey Unity de Coddy. Leçon 35 sur 50.
Certains utilitaires sont les mêmes pour tous les types : obtenir un composant ou l’ajouter, choisir une entrée au hasard dans un tableau. Une méthode générique permet de les écrire une seule fois, avec le type comme paramètre T que chaque appel renseigne :
public static class Helpers
{
public static T GetOrAdd<T>(this GameObject go) where T : Component
{
if (!go.TryGetComponent(out T found)) found = go.AddComponent<T>();
return found;
}
public static T RandomItem<T>(T[] items)
{
return items[Random.Range(0, items.Length)];
}
}Rigidbody body = crate.GetOrAdd<Rigidbody>();
Color paint = Helpers.RandomItem(colors);
GameObject enemy = Helpers.RandomItem(enemyPrefabs);where T : Component est une garantie concernant T, qui détermine ce que la méthode peut faire avec lui. AddComponent n’accepte que des composants, donc sans la contrainte, le compilateur refuse go.AddComponent<T>() ; avec cette contrainte, n’importe quel composant convient, qu’il s’agisse du Rigidbody de Unity ou de tes propres scripts. La contrainte te donne aussi accès à tous les membres de Component sur un T, comme .transform et .gameObject. Une caisse qui possède déjà un Rigidbody récupère celui-ci, et rien n’est ajouté.
RandomItem n’a pas de contrainte, car elle ne manipule jamais T : elle fonctionne aussi bien avec des couleurs, des chaînes et des prefabs. Tu indiques rarement le type lors de l’appel : à partir de colors, un Color[], le compilateur déduit que T est Color. Une méthode qui prend IEnumerable<T> au lieu de T[] accepte aussi bien les tableaux que les Lists, y compris les tableaux renvoyés par FindObjectsByType<T>.
Défi
MoyenUne tour à impulsion se trouve dans la cour. Lorsque tu appuies sur Espace, elle émet une impulsion : les caisses situées à moins de 4 unités sont projetées vers le haut, et les lampes situées à moins de 4 unités s’allument. Lamp.cs est prêt, avec TurnOn(). Écris un helper qui trouve les deux :
- Dans
Helpers.cs, écris une classe statiqueHelpersavec une méthode génériqueInRange<T>(IEnumerable<T> items, Vector3 center, float range)pour tout type de composant. Elle renvoie uneList<T>contenant les éléments dont la position se trouve à une distance inférieure ou égale àrangedecenter. - Dans
Pulse.cs, lorsque tu appuies sur Espace : chaque Rigidbody de la scène situé à une distance inférieure ou égale àrangede la tour reçoit une impulsion vers le haut delift, et chaque Lamp situé à une distance inférieure ou égale àranges’allume. Utilise InRange pour les deux, sur les tableaux que te fournitFindObjectsByType.
Appuie sur Jouer, appuie sur Espace, puis sur Vérifier.
Essayez vous-même
using System.Collections.Generic;
using UnityEngine;
// Helpers.InRange<T> : les éléments à portée d'un point
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’objets8Code réutilisable
Méthodes d’extensionUn singleton génériqueFonctions utilitaires génériquesRécapitulatif : FindNearest