Unité maintenant, vous pensez aux composants

Bien qu'Unity soit une plate-forme de jeu incroyable, s'y habituer nécessitera un peu de travail initial, car vous devrez probablement modifier vos rouages ​​cognitifs pour en saisir le sens. à base de composants architecture.

Bien que la programmation orientée objet (OOP) classique puisse être utilisée, et qu'elle soit utilisée, le flux de travail de Unity s'appuie fortement sur la structure des composants, ce qui nécessite une réflexion basée sur les composants. Si vous connaissez les composants, c'est parfait. sinon, ce n'est pas un problème. Ici, je vais vous donner un cours intensif sur les composants dans Unity.

Image d'aperçu: Old Cogs by Emmanuel Huybrech.


Qu'est-ce qu'un composant?

Avant de commencer à travailler et à réfléchir avec les composants, assurons-nous de bien comprendre en quoi ils consistent..

Dans le monde de la programmation, les concepts de composants et de découplage vont de pair. Un composant peut être considéré comme une pièce plus petite d'une machine plus grande. Chaque composant a son propre travail spécifique et peut généralement (de manière optimale) accomplir sa tâche ou son objectif sans l'aide de sources extérieures. De plus, les composants appartiennent rarement à une seule machine et peuvent être associés à divers systèmes pour accomplir leur tâche spécifique, mais obtiennent des résultats différents lorsqu'il s'agit d'une vision d'ensemble. En effet, non seulement les composants ne se soucient pas de cette image plus grande, mais également ne sais même pas qu'il existe.

Un exemple classique de composants sont les pièces d’une voiture, mais c’est ennuyeux, car je n’aime pas trop les voitures. Au lieu de cela, considérons un contrôleur Xbox 360. Tt a deux sticks analogiques, divers boutons, déclencheurs, etc. Non seulement l’automate tout entier est-il un composant, mais chaque aspect de l’automate est un composant.

Photo de Futurilla.

Le bouton X peut: être appuyé; envoyer l'information qu'elle a été pressée; être libéré; et envoyer des informations qui ont été publiées. Il n'a aucune idée qu'il y a divers autres boutons juste à côté, et il ne s'en soucie pas.

Le contrôleur lui-même est un composant, composé d'autres composants (tous les boutons, manettes de jeu et déclencheurs), car il peut envoyer des données à tout ce qui est branché, mais il se fiche de la nature de cet objet (Xbox, PC, Création Arduino, ou autre). Ni le bouton X, ni le contrôleur lui-même, n'a besoin de savoir à quel jeu vous jouez, car il fera toujours son travail, quel que soit le destinataire de ses informations.. 

La fonction du contrôleur est une rue à sens unique, et sa tâche ne changera jamais en raison de ce à quoi il est branché. Cela en fait un composant performant, à la fois parce qu'il peut faire son travail en tant que périphérique autonome, mais aussi parce qu'il peut faire son travail avec plusieurs dispositifs.


Pourquoi et comment l'unité privilégie-t-elle les composants??

L'unité a été construite avec des composants en tête, et cela se voit. L'un des aspects les plus précieux et distinctifs d'Unity est qu'il s'agit d'un programme très visuel. Je travaille dans le développement de jeux depuis des années et, mis à part mes débuts avec l'IDE Flash, j'ai surtout travaillé avec des feuilles de sprite PNG et un éditeur de code tel que FlashDevelop, qui n'est pas du tout visuel..

L'unité est l'exact opposé. Unity vous permet de voir tout ce sur quoi vous travaillez et en temps réel. Cela signifie que vous pouvez tester votre projet, le voir s'exécuter dans une fenêtre séparée, apporter des modifications à votre code ou aux objets du jeu et voir ces modifications reflétées en direct. La puissance fournie par ce système à un développeur est immense et constitue à présent, à mon avis, un aspect essentiel du développement de jeux modernes. Tout cela est rendu possible par l'architecture à base de composants d'Unity..

L'inspecteur

Si vous ne connaissez pas Unity, je vais expliquer l'inspecteur. Il s'agit d'un panneau dans Unity qui vous montre toutes les propriétés d'un objet de jeu. Si vous cliquez sur votre lecteur dans le monde (au moment de l'exécution ou avant), vous pourrez voir tout ce qui concerne cet objet..

Si votre avatar de joueur contient six composants, chacun d'entre eux sera répertorié dans un onglet séparé et chaque variable publique sera disponible pour que vous puissiez la voir et l'ajuster. Si votre avatar de joueur a un inventaire, vous verrez non seulement qu’il a un inventaire, vous pourrez également voir les éléments de cet inventaire et l’index de la liste ou de la matrice occupée par chaque élément. Si vous récupérez un nouvel élément dans le jeu pendant que vous testez, vous le verrez ajouté à l'inventaire en direct. Vous pouvez même ajouter ou supprimer des objets de cet inventaire, ce qui vous permettrait de tester rapidement de nouveaux objets que vous pourriez même créer. pendant que le jeu fonctionne.

L'inspecteur de l'unité.

Bien que l'édition en direct soit incroyablement puissante, elle ne dépend pas exactement de l'utilisation de composants. Vous pouvez modifier un script et voir ces modifications reflétées en direct, mais cela limite par rapport à ce que les composants vous permettent de faire..

Considérons un tireur de l'espace vertical. Lorsque vous testez votre projet dans la plupart des environnements, vous verrez comment votre jeu est joué, prenez des notes, puis revenez dans le code et modifiez les choses, uniquement pour compiler à nouveau le projet et tester ces points. Si vous avez une configuration en direct, vous pouvez modifier ce code à la volée et voir ces changements en cours de lecture, ce qui est encore mieux. Cela dit, si vous n'utilisez pas de composants, vous devrez changer beaucoup de code pour voir les effets majeurs, ce qui prend du temps, ce qui va plutôt à l'encontre du but de l'édition en direct..

Si vous travaillez avec des composants, vous pouvez ajouter de nouveaux composants en deux secondes à plat. Vous pouvez échanger les canons de votre vaisseau contre les canons utilisés par un boss (en supposant que vous programmiez vos composants pour fonctionner de manière autonome, comme le feraient de bons composants), vous pouvez modifier votre système de santé à cinq coupses en un bouclier de recharge digne de Halo programmé pour un autre match. vous pouvez ajouter un tableau de sorts à l'un de vos personnages, le tout en quelques secondes.

Vous n'avez pas besoin de changer de code, vous n'avez pas besoin de recompiler, il vous suffit simplement de faire glisser et de déposer ou de sélectionner le composant souhaité dans une liste déroulante et l'ajouté. Ce type de pouvoir est précieux pour l’équilibrage du jeu et fait gagner un temps considérable..


Passer à la pensée par composants

La partie la plus difficile de l'utilisation de composants consiste à apprendre à structurer vos projets lors de leur utilisation. Pour la plupart des programmeurs, cela signifie probablement que vous allez créer beaucoup plus de scripts, chacun effectuant des tâches plus petites et plus spécifiques..

La façon dont vous communiquez entre les scripts est également un obstacle décent, car vous aurez beaucoup plus de morceaux et moins de classes géantes où chaque objet connaît chaque autre objet. Il existe évidemment des solutions, telles que les variables statiques pour les composants principaux de votre jeu (joueurs, score, etc.), mais cela fonctionne rarement pour tout (et ce n'est pas conseillé), et il existe des méthodes avancées pour structurer correctement vos composants. et rester découplé.

Heureusement, depuis que Unity a été construit avec des composants en tête, il possède un certain nombre de fonctions intégrées qui nous aident à atteindre cet objectif. Il existe des fonctions pour obtenir des références à un composant spécifique, pour vérifier tous les objets afin de voir lesquels contiennent un composant spécifique, etc. Avec ces différentes fonctions, vous pouvez facilement récupérer les informations nécessaires à la création de cette voie de connaissance à sens unique magique où les composants peuvent communiquer avec les objets qu’ils affectent, mais le composant lui-même n’a aucune idée de ce qu’est exactement cet objet. Combinez cela avec l'utilisation d'interfaces, et vous disposez de suffisamment de puissance de programmation pour adopter n'importe quelle approche du problème, simple ou complexe..

Exemple: types ennemis

Dans un système d’héritage en POO, vous pouvez avoir une base Ennemi classe qui contient toutes les fonctions que la plupart de vos ennemis utiliseraient, puis vous pouvez les étendre pour ajouter des fonctionnalités spécifiques.

Si vous avez déjà réellement implémenté un tel système, vous savez qu'entre votre base Ennemi classe, et peut-être votre base GameObject (ou équivalent), vous vous retrouvez avec beaucoup de fouillis inutiles d'avoir des variables et des fonctions dont certaines classes ont besoin, mais beaucoup ne le font pas. Des interfaces peut aider avec cela, mais ils ne sont pas toujours la solution.

Examinons maintenant la même configuration, mais en pensant aux composants. Vous avez encore divers ennemis, qui partagent tous de nombreuses fonctionnalités communes, mais qui ont chacun des caractéristiques uniques..

La première étape consiste à décomposer toutes les fonctionnalités. On pourrait penser que avoir la santé et mourant font partie du même système, mais même cet exemple peut être divisé en une composante du système de santé et une composante du système de décès. C'est parce que votre santé est votre santé et rien de plus. Lorsqu'il atteint zéro, ce n'est pas au système de santé de décider de la suite, mais au système de santé de savoir qu'il est en fait à zéro. D'autres systèmes, tels qu'un système de décès, peuvent lire ces informations, puis choisir de faire ce qui leur plaît.

Peut-être que le système de la mort engendrera un nouvel ennemi (pensez à un gros ennemi qui se fragmente en morceaux); peut-être que ça va laisser tomber un power-up; peut-être que ça va ajouter un effet d'explosion à l'écran. Peu importe ce qui se passe, le système de santé n'en fait pas partie, et c'est ainsi que nous fabriquons des composants propres et utiles..

Quand nous pensons au mouvement, nous pourrions penser que tout mouvement doit être dans un seul script. Mais dans certains jeux, certains ennemis ne peuvent pas marcher. ils ne peuvent que sauter. Certains ennemis peuvent marcher, mais ne peuvent pas sauter. Penser à ces choses, c'est comment nous repérons où des composants pourraient et devraient exister. En ce qui concerne la mobilité, nous pourrions séparer le saut de la marche ou de la course, séparer les vols et ainsi de suite, nous obtiendrions ainsi un code plus propre et plus de polyvalence..

Les composants rendent notre code plus propre (pas de variables ni de fonctions inutiles), mais ils rendent également le processus de création d’ennemis beaucoup plus flexible et agréable. Chaque composant de fonctionnalité ennemie étant configuré en tant que composant, nous pouvons faire glisser des aspects d’un ennemi et voir son comportement, et même en temps réel, si nous utilisons Unity..

Supposons que toutes les caractéristiques suivantes sont déjà programmées. Au cours du processus de création de notre ennemi, nous pourrions créer trois ennemis vierges, qui sont tous des préfabriqués vides dans Unity. Nous pouvons alors faire glisser un système de santé, un système de dépose d’objet et un système de mort, car nous savons que tous nos ennemis, quelles que soient leurs différences, seront en santé, mourront et abandonneront un objet. En fait, nous pouvons sélectionner les trois préfabriqués en même temps, puis faire glisser ces composants dans le panneau Inspecteur et les mettre à jour simultanément..

Ensuite, nous savons qu’un ennemi sera capable de voler, nous avons donc choisi cet ennemi et traîné un en volant composant sur elle. Un autre peut repérer une cible dans le jeu et tirer dessus, nous jetons donc un tirer sur la cible script composant. Le troisième peut créer une barrière qui bloque toutes les attaques pendant une courte durée, aussi jetons-nous sur barrière composant.

Nous avons maintenant trois ennemis uniques, qui partagent tous certains composants, mais qui possèdent également des composants qui ne s’appliquent qu’à eux. Ce qui est agréable, c’est que faire de ces ennemis est simple et qu’expérimenter de nouvelles variations est aussi simple que de glisser-déposer. Vous voulez un ennemi volant, avec une barrière, qui peut cibler un ennemi et lui tirer dessus? Faites glisser tous les composants ci-dessus sur un seul ennemi, et vous avez juste cela!


Conclusion

Penser avec des composants peut ne pas être facile, mais cela présente certainement des avantages. Vous continuerez à utiliser à la fois les composants et l'héritage dans vos futurs programmes, mais il est extrêmement utile d'élargir votre multitude de façons d'aborder le même problème en considérant différentes perspectives..

En ce qui concerne Unity, vous pouvez utiliser la méthode de votre choix, mais les composants sont définitivement privilégiés et il n’a aucun sens de lutter contre un flux de travail aussi incroyable. Apprendre à utiliser l’unité et changer ma façon de penser pour travailler avec des composants a été un obstacle moyennement difficile à surmonter, mais maintenant que je suis ici, je ne me vois pas revenir si tôt.