Comment est formé un personnage dans l'Unreal Engine ?
Comme indiqué dans la section Mode de jeu / État de jeu, le cadre de gameplay Unreal permet de comprendre le fonctionnement des personnages dans l'Unreal Engine. Concrètement, un joueur est constitué d'un pion représentant sa présence physique dans le monde du jeu et d'un contrôleur qui détermine son comportement. Ce découplage est utile pour l'IA ainsi que pour la réplication réseau. À titre de référence, la hiérarchie se présente comme suit :
Commençons par l'importation des ressources et la création du pion pour passer ensuite au contrôleur de joueur. Pour Parrot, notre héros contrôlé par le joueur sera le Capitaine Barbarossa (visitez le site web de Quaternius pour obtenir le Pirate Kit fourni par Quaternius).
Importation de ressources artistiques
Dans l'outil de modélisation 3D de votre choix, exportez votre maillage et vos animations dans un format compatible avec le moteur. Ici, les développeurs ont utilisé le format .fbx. Les ressources de Barbarossa se trouvent sous Content/Assets/Quaternius/PirateKit/Characters/Barbarossa. Vous pouvez importer votre fichier .fbx en faisant un clic droit sur le menu contextuel ou en le glissant-déposant dans le navigateur de contenu. Vous obtiendrez une fenêtre de paramètres d'importation du fichier .fbx. Choisissez les options adaptées à votre importation. Dans ce cas, assurez-vous qu'aucun squelette existant n'est sélectionné et que l'option Importer les animations est cochée. Il est également nécessaire de créer un nouveau matériau d'atlas qui puisse être indexé par votre maillage. Ce matériau peut être réutilisé dans toutes les ressources du Pirate Kit. Vous devriez maintenant avoir ces 3 fichiers et toutes les animations incluses dans votre fichier .fbx.
Par souci de propreté, les fichiers de la séquence d'animation sont situés sous le dossier Animations, à côté des 3 fichiers :
Squelette, maillage squelettique et ressources physiques
Un squelette est une hiérarchie utilisée pour définir les os (parfois appelés articulations) dans un maillage squelettique. Ces os doivent correspondre au squelette dans votre outil de modélisation 3D. Les squelettes peuvent être réutilisés d'un maillage squelettique à l'autre, à condition d'être compatibles. Vous remarquerez également qu'une ressource physique a été créée. Les ressources physiques définissent la physique et les collisions utilisées par un maillage squelettique. Elles contiennent des corps rigides et des contraintes pour la simulation. Vous ne pouvez avoir qu'une seule ressource physique par maillage squelettique, et ce type de ressource peut être activé ou désactivé selon certaines conditions. Vous pouvez ajuster les ressources physiques à mesure de leur importation ou créer de nouvelles ressources à partir d'un maillage squelettique.
Blueprint d'animation
Maintenant que vous disposez d'un maillage squelettique, vous pouvez commencer à l'animer à l'aide du blueprint d'animation. Ce dernier est similaire au système d'animation Mecanim de Unity. Le graphique d'animation dans les blueprints d'animation devrait vous être familier, car ils fonctionnent de la même manière. Ces deux systèmes sont dotés d'une logique conditionnelle qui permet de passer d'un état d'animation à un état de sortie final. Dans votre dossier, créez un nouveau blueprint d'animation à partir du menu contextuel et sélectionnez votre squelette. Notre blueprint d'animation s'appellera ABP_Captain_Barbarossa sous Content/Blueprints/Player.
Sur le côté gauche de l'inspecteur de blueprint, vous remarquerez qu'il y a deux graphiques : le graphique d'événements et le graphique d'animation. Le graphique d'animation est la machine à état qui contrôle la pose finale. Le graphique d'événements est l'endroit où vous pouvez définir toute logique liée à l'animation. Contrairement à Unity, où vous devez transmettre des données au composant Mecanim, les blueprints d'animation peuvent extraire ce dont ils ont besoin lors d'un événement donné. Par exemple, dans le cas où vous voudriez interroger la vitesse du personnage et faire en sorte que votre animation se base sur cette valeur. Une bonne façon de le faire est d'utiliser le nœud d'animation Initialiser du blueprint d'événement dans le graphique d'événements, puis Obtenir l'acteur propriétaire. Enfin, mettez en cache le composant d'animation dans une variable. À partir de là, à chaque tick de BlueprintThreadSafeUpdateAnimation, vous pouvez interroger la vitesse directement à partir de votre composant de déplacement. Les variables peuvent également être partagées entre le graphique d'événements et le graphique d'animation.
N'hésitez pas à explorer plus en profondeur le blueprint d'animation configuré pour Barbarossa. En double-cliquant sur les nœuds, vous pouvez voir comment les machines à état, les états et les règles d'état sont configurés pour la pose de sortie finale. Il y a également des exemples d'utilisation d'un lecteur de séquence et d'utilisation d'un espace de fusion. De même, le graphique d'événements montre comment l'animation est pilotée par les données des personnages ; cette relation deviendra plus claire au fil de cet article.
Pion
Maintenant qu'il existe un maillage squelettique qui peut être animé, vous pouvez commencer à créer votre pion qui sera utilisé par le mode de jeu. Les développeurs ont choisi de s'appuyer sur la classe Character par défaut de l'Unreal Engine, qui est une classe enfant de la classe C++ Pawn par défaut. La classe Character dispose d'un composant Déplacement du personnage qui est particulièrement utile pour ce jeu et constitue une autre classe sur laquelle vous pouvez vous appuyer.
Le pion du joueur et celui de l'ennemi ont des fonctionnalités communes, comme les points de vie, la sensibilité aux coups et l'élimination. Cette fonctionnalité est partagée par la création d'une classe C++ AParrotCharacterBase qui hérite de ACharacter. Cette classe constitue une bonne version de base pour l'élaboration d'un comportement divergent entre le pion de l'ennemi et celui du joueur.
Ensuite, créez une classe C++ AParrotPlayerCharacter pour gérer la logique propre au joueur. Enfin, vous créerez un blueprint pour gérer la représentation visuelle de votre personnage. Le blueprint de Parrot est BP_ParrotPlayerCharacter, sous Content/Blueprints/Player. La hiérarchie de l'héritage se présente comme suit :
En ouvrant BP_ParrotPlayerCharacter, vous devriez voir quelques composants sous l'inspecteur de composants à gauche de la fenêtre de l'éditeur. Le composant Maillage est l'endroit où vous pouvez paramétrer votre ressource de maillage squelettique ainsi que le blueprint d'animation sous la classe Anim. Si le maillage n'est pas positionné correctement, vous pouvez ajuster les valeurs de transformation pour l'aligner sur le composant de votre capsule. Vous devriez obtenir un résultat similaire à celui-ci :
Ensuite, vous pouvez attribuer la classe de pion par défaut au blueprint dans la ressource de mode de jeu.
Vous avez maintenant un pion animé qui peut être utilisé dans le jeu !
Contrôleur de joueur
Maintenant que vous avez un pion utilisable à disposition, vous pouvez créer le contrôleur de joueur. Les contrôleurs de joueur représentent essentiellement la volonté du joueur humain. Lors de la création de votre jeu, il convient de réfléchir à la définition des événements d'entrée. Pour les jeux simples où les pions ne changent pas, le pion convient. Cependant, pour les comportements complexes, le contrôleur de joueur est une meilleure option. Les pions sont éphémères et peuvent être possédés ou non par des contrôleurs de joueur. Les pions peuvent apparaître ou être détruits tandis que les contrôleurs de joueur persistent tout au long du jeu.
Vous n'aurez besoin d'aucune logique C++ dans le contrôleur de joueur, il vous suffit donc de créer un blueprint pour faire le nécessaire. BP_ParrotPlayerController se trouve sous Content/Blueprints/Player. La hiérarchie de l'héritage se présente comme suit :
Dans le blueprint, vous remarquerez qu'il y a des nœuds d'événements d'entrée qui mènent à une logique de gameplay de base. Ces événements d'entrée sont spécifiquement liés au plug-in Enhanced Input. Vous pouvez en apprendre plus sur cette configuration dans la rubrique Enhanced Input. Nous pouvons mettre en cache le pion du joueur sur Begin Play pour appeler les fonctions de déplacement de base plus tard. Par exemple Add Movement Input, Jump et StopJump.
Passons aux tests ! Dans le blueprint du mode de jeu, définissez la classe du nouveau contrôleur de joueur, puis vérifiez que vous pouvez utiliser le contrôleur en jeu :
Dans ce menu déroulant dans l'éditeur de niveau, vérifiez que le bon mode de jeu est sélectionné :
Enfin, assurez-vous que votre carte dispose d'un acteur PlayerStart et d'une caméra visible. Lorsque vous appuyez sur le bouton Jouer, vous devriez voir votre personnage se déplacer et s'animer :
Composant de déplacement du personnage
La classe de base ACharacter intègre de nombreuses fonctionnalités. Le composant d'acteur UCharacterMovement en est un exemple. Le composant de déplacement du personnage gère toute la logique de déplacement du personnage dans le monde. Il prend en charge les modes de marche, de course, de chute, de natation, de vol et de déplacement personnalisé. Il vaut vraiment la peine de l'explorer par soi-même pour se faire une idée du fonctionnement des déplacements de base du personnage et de la puissance des composants d'acteur.
Pour Parrot, le composant de base de déplacement du personnage n'a pas fourni la sensation de jeu que les développeurs recherchaient au départ. Toutefois, il a fourni une base solide sur laquelle s'appuyer. La classe C++ UParrotCharacterMovementComponent dérive de UCharacterMovementComponent. Nous pouvons alors paramétrer le composant de déplacement sur le composant de déplacement CDO dans BP_ParrotPlayerCharacter comme suit :
Mais que fait réellement le composant de déplacement de Parrot ? Il vous permet en fait de définir un saut de type "jeu de plateforme" en remplaçant les fonctionnalités du composant de déplacement de base liées au saut. En utilisant certaines valeurs réglables lors de la conception, lorsqu'un saut se produit, vous pouvez modifier la gravité et la vitesse de saut du joueur afin d'atteindre une hauteur maximale dans un laps de temps déterminé. Une fois cette hauteur atteinte, vous pouvez commencer à appliquer une gravité descendante. Si le joueur relâche la commande de saut trop tôt, vous pouvez appliquer un multiplicateur pour augmenter la gravité.
On obtient ainsi un saut qui ressemble plus à ce que l'on attend d'un jeu de plateforme qu'à une simple impulsion sur l'axe Z.
Grâce au gros du travail effectué par le composant de déplacement du personnage de base, vous pouvez focaliser la logique du composant de déplacement sur les sauts. Les valeurs de l'inspecteur pour BP_ParrotPlayerCharacter sur le composant de déplacement valent également la peine d'être examinées pour obtenir une vue d'ensemble de la façon dont toutes les pièces du composant de déplacement fonctionnent ensemble. La logique de déplacement peut être étendue pour s'adapter à divers types de cas d'utilisation.