Cette fonctionnalité est en accès anticipé. Les îles que vous publiez peuvent proposer cette fonctionnalité, mais sachez que pendant la période d'accès anticipé, toute modification risque de perturber votre île et de nécessiter votre intervention.
Le générateur de PNJ a besoin d'une piste de durée de vie de liaison dans Sequencer. Il n'y a aucun moyen d'ajouter rétroactivement cette piste à des séquences existantes créées avant la version 31.00. Vous devez republier toute île utilisant un générateur de PNJ dans une séquence après avoir ajouté la piste de durée de vie de liaison.
Pour ajouter une piste de durée de vie de liaison :
-
Cliquez sur l'icône + à côté du générateur de PNJ dans la liste des pistes.
-
Sélectionnez Durée de vie de liaison dans le menu déroulant.
Utilisez Sequencer pour créer des animations personnalisées de personnages à jouer de différentes manières et sur plusieurs appareils, y compris le générateur de PNJ. Utilisez des événements ou Sequencer associé aux appareils Séquence cinématique pour définir et jouer des animations avec un modèle de comportement le long de certains points du chemin de patrouille de l'IA.
Vous pouvez importer et migrer les animations personnalisées depuis l'Unreal Engine (UE), y compris les MetaHumans. Pour ce faire, vous devrez peut-être recibler le maillage squelettique pour l'adapter aux PNJ, les personnages Fortnite disposant de leur propre structure squelettique.
Les personnages MetaHuman sont gourmands en mémoire. Il est préférable de limiter le nombre de ressources MetaHuman que vous utilisez.
Animation de PNJ dans Sequencer
Le générateur de PNJ offre une grande variété de possibilités de jeu pour votre projet, qu'il s'agisse de personnages interactifs ou de scènes cinématiques informatives. Créez des animations personnalisées pour le générateur de PNJ avec le [squelette de contrôle] (https://docs.unrealengine.com/rigging-with-control-rig-in-unreal-engine/). Vous pouvez aussi importer des animations achetées ou créées dans d'autres logiciels.
Vous pouvez également utiliser le squelette de contrôle CD pour animer les PNJ avec une animation reciblée ou une emote.
Pour en savoir plus sur les flux d'animation du squelette de contrôle CD, consultez la documentation de l'UE.
Pour capturer des animations avec des PNJ, procédez comme suit.
-
Faites un clic droit dans le navigateur de contenu pour créer une séquence de niveau.
-
Renommez la vignette de votre Séquence de niveau.
-
Double-cliquez sur la vignette de votre Séquence de niveau pour ouvrir l'éditeur de Sequencer.
-
Cliquez sur +Piste, puis sélectionnez Envoyer vers Sequencer > Générateur de PNJ. Cela ajoute le générateur de PNJ à la piste Séquence de niveau.
Vous pouvez faire glisser le générateur de PNJ dans la liste des pistes depuis l'organiseur pour l'ajouter à la séquence de niveau.
-
Cliquez sur l'icône + à côté du générateur de PNJ dans la liste des pistes et sélectionnez Squelette de contrôle > Classes de squelette de contrôle > Squelette de contrôle CD. Cela ajoute le squelette du PNJ à la piste, vous donnant accès à chaque os du squelette afin de les manipuler et de les enregistrer.
-
Sélectionnez les os que vous souhaitez déplacer dans le hublot, dans l'organiseur d'animation ou dans Sequencer et donnez-leur une position de départ pour votre animation.
-
Définissez la première image clé en cliquant sur l'icône + à côté des os que vous avez déplacés.
Si vous avez créé ou acheté une animation sous forme de fichier de séquence d'animation FBX, vous pouvez l'ajouter à la piste d'animation de la chronologie d'un générateur de PNJ en cliquant sur l'icône + à côté du générateur de PNJ et en sélectionnant Animation > Fichier d'animation.
Continuez de déplacer les os et de définir de nouvelles images clés dans la chronologie de Sequencer jusqu'à ce que l'animation soit terminée. Une fois l'animation terminée, jouez-la dans Sequencer pour vous assurer que le mouvement correspond à vos préférences.
Un moyen simple de lire une animation à l'envers consiste à faire un clic droit sur le fichier d'animation dans la chronologie et à sélectionner Propriétés > Inverser.
Lorsque le résultat vous convient, il est temps de précalculer l'animation sur le maillage squelettique. Faites un clic droit sur le générateur de PNJ et sélectionnez Précalculer la séquence d'animation.
Assurez-vous que les membres de votre maillage squelettique ne couvrent pas d'autres parties du maillage squelettique à la lecture de l'animation.
Enregistrement des attributs comportementaux
Vous pouvez également utiliser les attributs comportementaux avec le générateur de PNJ. Les options de comportement déterminent la caractéristique élémentaire que le PNJ hérite des PNJ de Fortnite Battle Royale. Ces caractéristiques déterminent si le PNJ agit comme un garde ou comme un animal sauvage.
Pour plus d'informations sur le mode de définition des attributs comportementaux avec le générateur de PNJ, référez-vous au document [Définition de PNJ] (npc-character-definitions-in-unreal-editor-for-fortnite).
Une fois ces attributs comportementaux configurés, vous pouvez définir les animations en images clés dans une séquence de niveau et les jouer sur un appareil de séquence cinématique pendant le jeu. Contrairement aux étapes précédentes, vous n'avez pas besoin de précalculer la performance dans le squelette de contrôle puisque le comportement est défini dans les options du générateur de PNJ.
Vous pouvez également utiliser l'animation que vous avez créée ou le comportement hérité avec l'appareil Nœud de chemin de patrouille des IA et enregistrer le PNJ qui suit le chemin que vous avez créé avec l'acteur caméra de cinéma.
Liaisons de PNJ spawnable et remplaçables
Il existe désormais deux nouvelles façons d'importer un PNJ dans vos séquences : la liaison de PNJ spawnable et la liaison de PNJ remplaçable. Ces liaisons sont créées à partir de définitions de PNJ.
Liaison de PNJ spawnable
À l'aide d'une séquence cinématique, la liaison de PNJ spawnable peut générer un acteur dans le monde sur la base d'une définition de PNJ. Ce PNJ peut être animé dans Sequencer de la même manière que n'importe quel maillage squelettique.
Pour créer une liaison de PNJ spawnable, glissez simplement votre définition de PNJ dans Sequencer :
Cliquez sur le GIF pour l'agrandir.
La liaison spawnable peut être animée comme n'importe quel autre acteur à maillage squelettique. Exemple :
-
Cliquez sur + Animation (Ajouter une animation) et sélectionnez un emote de danse pour la définition du PNJ.
Cliquez sur le GIF pour l'agrandir.
-
Déplacez votre tête de lecture plus en avant, faites glisser votre PNJ vers un nouvel emplacement et définissez une nouvelle image clé. Le PNJ se déplacera désormais du point A au point B.
Cliquez sur le GIF pour l'agrandir.
Liaison de PNJ remplaçable
La liaison de PNJ remplaçable prend le contrôle d'un PNJ généré dans le monde et le place dans votre séquence. Elle peut ensuite jouer des animations créées dans Sequencer. Pendant que le PNJ est lié par le Séquenceur, tout comportement, perception et pathfollowing est suspendu. Ceux-ci reprennent lorsque le PNJ est libéré.
Le PNJ est replacé à son emplacement d'origine lorsqu'il n'est plus lié.
Pour créer une liaison de PNJ remplaçable, créez une liaison de PNJ spawnable, faites un clic droit sur votre liaison, et choisissez Convert selecting binding to > Replaceable NPC Character (Convertir la liaison sélectionnée en > PNJ remplaçable).
Cliquez sur le GIF pour l'agrandir.
Après la conversion, la piste est remplacée par une piste de durée de vie de liaison. Toutes les modifications apportées à la liaison spawnable sont conservées.
Pour que le PNJ soit trouvé et lié pendant le jeu, vous devez ajouter un modificateur à la définition du PNJ : le modificateur du Sequencer. Vous pouvez ajouter ce modificateur à votre définition de PNJ en utilisant la même méthode que pour les autres modificateurs. Si vous n'ajoutez pas ce modificateur, vous obtiendrez un échec de validation.
Cliquez sur le GIF pour l'agrandir.
Le modificateur de Sequencer a une propriété Identificateur unique. Cette propriété est utilisée pour localiser le PNJ généré dans le jeu. La valeur par défaut est le nom de la définition de PNJ. Notez que si deux définitions de PNJ différentes ont le même identificateur unique, les deux peuvent être liées lorsque votre séquence est jouée pendant la partie.
Lecture de séquences en cours de partie
Pour jouer votre séquence, utilisez normalement l'appareil Séquence cinématique.
Une liaison spawnable n'a pas besoin d'une configuration supplémentaire pour être jouée.
Une liaison remplaçable nécessite l'ajout d'un générateur de PNJ dans votre monde qui utilise votre définition de PNJ. Si la liaison remplaçable ne parvient pas à trouver un PNJ auquel se lier, vous verrez la ligne suivante dans le journal de votre client :
LogFortNPCMovieSceneBindings : Avertissement : Liaison impossible à un pion à l'aide d'une définition de garde PNJ. Veuillez vous assurer qu'il y a au moins un PNJ généré.
Si vous voulez faire apparaître le PNJ au moment où votre séquence doit être jouée. Pensez à utiliser une liaison spawnable ou à accrocher l'événement À l'apparition à la fonction de lecture sur l'appareil Séquence cinématique.
Blueprint personnalisé de PNJ
La plupart des types de PNJ sont liés en tant que maillages squelettiques, à l'exception d'une définition de PNJ qui utilise un blueprint personnalisé.
Cela lie le blueprint et expose des composants supplémentaires, tels que des effets visuels, qui peuvent ensuite être modifiés dans le Sequencer.
On peut voir ici qu'un système de particules Niagara a été modifié dans le Sequencer pour faire exploser la tête du PNJ :
Cliquez sur le GIF pour l'agrandir.
Restrictions connues
- Les liaisons de PNJ remplaçables ne peuvent être utilisées qu'avec l'appareil Séquence cinématique configuré sur Visibilité : Tout le monde. L'utilisation de tout autre paramètre de visibilité entraîne l'échec de la validation.
- Les tentatives d'utilisation d'une liaison de PNJ remplaçable avec des PNJ de faune chevauchables ou domptables échoueront à la validation.
- Les liaisons de PNJ remplaçables qui utilise une définition de PNJ ne peuvent pas utiliser l'option Forcer la conservation de l'état sur l'option utilisateur Remplacement de l'état d'achèvement. L'utilisation de cette option entraîne l'échec de la validation.
- Lorsqu'un PNJ est lié par le Sequencer, il se fixe en place. En outre, les problèmes de latence peuvent provoquer des bogues visuels très courts lorsque le PNJ est lié et délié. Il est donc fortement conseillé d'utiliser des techniques telles que l'apparition du PNJ hors champ, les fondus d'écran, les effets visuels ou la piste de visibilité lors de l'utilisation d'une liaison de PNJ remplaçable.
Appeler des animations avec Verse
En exposant les animations à Verse à l'aide du rendu des ressources, vous pouvez jouer des animations personnalisées sur vos PNJ à l'aide du module d'animation.
Interface du contrôleur d'animation
L'interface play_animation_controller permet de jouer une animation sur un personnage et peut être récupérée avec la fonction GetPlayAnimationController(). Cette interface expose deux fonctions qui jouent des animations : la fonction synchrone Play() et la fonction asynchrone PlayAndAwait().
Les deux fonctions acceptent les paramètres suivants :
| Option | Valeur | Description |
|---|---|---|
| Animation | Sélectionner une animation | L'animation à jouer. Doit spécifier une animation dans le fichier projet Assets.digest.verse. |
| PlayRate | 1,0, sélectionner une fréquence de lecture. | La vitesse de lecture de l'animation. Une valeur de 1,0 correspond à la vitesse par défaut de l'animation. |
| BlendInTime | 0,0, sélectionner un BlendInTime | La durée de transition entre l'animation précédente et l'animation actuelle. |
| BlendOutTime | 0,0, sélectionner un BlendOutTime | La durée de transition entre l'animation actuelle et la suivante. |
| StartPositionSeconds | 0,0, sélectionner une StartPositionSeconds | La position en secondes à partir de laquelle jouer l'animation. |
Fonction Play And Await
La fonction PlayAndAwait() joue une animation de manière asynchrone et renvoie une instance de play_animation_result enum, qui contient trois valeurs : Completed, Interrupted et Error. Elles correspondent respectivement à une animation terminée, à une animation interrompue et à une erreur survenue. En interrogeant cette énum, vous pouvez exécuter un code différent en fonction du résultat de votre animation.
AnimationResult := PlayAnimController.PlayAndAwait(MyAnimation)
case(AnimationResult) :
play_animation_result.Completed => Print("Animation terminée !")
play_animation_result.Interrupted => Print("Animation interrompue.")
play_animation_result.Error => ("Une erreur est survenue pendant l'animation.")
Fonction Play
La fonction Play() s'exécute de manière synchrone et renvoie une instance de la classe playing_animation_instance. La classe playing_animation_instance permet d'interroger et de manipuler une animation en cours et contient les valeurs suivantes :
| Valeur | Explication |
|---|---|
| GetState() | Cette fonction renvoie l'état actuel de la lecture de l'animation dans une énum play_animation_state. |
| Stop() | Cette fonction arrête l'animation en cours. |
| CompletedEvent | Cet événement est déclenché lorsqu'une animation est terminée |
| InterruptedEvent | Cet événement est déclenché lorsqu'une animation est interrompue. |
| BlendedInEvent | Cet événement est déclenché à la fin de la transition de sortie d'une animation. |
| BlendingOutEvent | Cet événement est déclenché lorsqu'une animation commence sa transition de sortie. |
| Await() | Cette fonction attend que l'animation se termine ou soit interrompue. Notamment, elle renvoie une énum play_animation_result et est fonctionnellement identique à l'appel de PlayAndAwait(). |
Vous pouvez utiliser la fonction Play() pour manipuler des animations en cours ou exécuter un code lorsque certaines conditions de votre animation sont remplies.
# Jouer une animation de manière synchrone et récupérer son instance d'animation
AnimationInstance := PlayAnimController.Play(MyAnimation, ?PlayRate := PlayRate, ?BlendInTime := BlendInTime, ?BlendOutTime := BlendInTime, ?StartPositionSeconds := StartPositionSeconds)
# S'abonner à une fonction qui s'exécute une fois l'animation terminée
AnimationInstance.CompletedEvent.Subscribe(OnAnimationComplete)
Sleep(1.0)
AnimationState := AnimationInstance.GetState()
# Si l'animation est toujours en cours au bout d'une seconde, arrêter l'animation.
if(AnimationState = play_animation_state.BlendingOut):
AnimationInstance.Stop()
Exemple de lecture d'animation
Le code ci-dessous donne un exemple de comportement de PNJ qui utilise le module d'animation pour lire une animation. Notez que toute animation personnalisée à lancer pour vos personnages doit d'abord être exposée à Verse via le rendu des ressources et doit apparaître dans le fichier Assets.digest.verse. Dans cet exemple, l'animation MyAnimation se trouve dans le module Animations du personnage personnalisé MyCharacter dans Assets.digest.verse, et est donc appelée via MyCharacter.Animations.MyCharacter.
using { /Fortnite.com/AI }
using { /Fortnite.com/Animation/PlayAnimation }
using { /Verse.org/Simulation }
using { /Fortnite.com/Characters }
basic_play_anim_example := class(npc_behavior):
# La vitesse de lecture de l'animation.
@editable
PlayRate : float = 1.0
# Durée de transition de l'animation précédente
# à l'animation actuelle.
@editable
BlendInTime : float = 0.25
# Durée de transition de l'animation en cours
# à la suivante.
@editable
BlendOutTime : float = 0.25
# La position en secondes à partir de laquelle commencer
# à jouer l'animation.
@editable
StartPositionSeconds : float = 0.0
# Délai d'attente avant de redémarrer l'animation.
@editable
SleepDuration : float = 2.0
OnBegin<override>()<suspends>:void=
if:
# Obtenir le contrôleur d'animation du PNJ
Agent := GetAgent[]
FortCharacter := Agent.GetFortCharacter[]
PlayAnimController := FortCharacter.GetPlayAnimationController[]
then:
AnimationResult := PlayAnimController.PlayAndAwait(MyCharacter.Animations.MyAnimation, ?PlayRate := PlayRate, ?BlendInTime := BlendInTime, ?BlendOutTime := BlendInTime, ?StartPositionSeconds := StartPositionSeconds)
# Afficher le résultat d'exécution de l'animation.
case(AnimationResult) :
play_animation_result.Completed => Print("Animation terminée !")
play_animation_result.Interrupted => Print("Animation interrompue.")
play_animation_result.Error => ("Une erreur est survenue pendant l'animation.")
Sleep(SleepDuration)
# Jouer une animation de manière synchrone et obtenir son instance d'animation.
AnimationInstance := PlayAnimController.Play(MyCharacter.Animations.MyAnimation, ?PlayRate := PlayRate, ?BlendInTime := BlendInTime, ?BlendOutTime := BlendInTime, ?StartPositionSeconds := StartPositionSeconds)
Sleep(SleepDuration)
AnimationState := AnimationInstance.GetState()
# Afficher l'état actuel de l'animation.
case(AnimationState):
play_animation_state.Playing => Print("Animation en cours de lecture !")
play_animation_state.BlendingIn => Print("Transition d'entrée de l'animation !")
play_animation_state.BlendingOut => Print("Transition de sortie de l'animation !")
play_animation_state.Completed => Print("Animation terminée !")
play_animation_state.Stopped => Print("Animation arrêtée !")
play_animation_state.Interrupted => Print("Animation interrompue !")
play_animation_state.Error => Print("Une erreur est survenue pendant l'animation")
else:
Print("Impossible d'obtenir le contrôleur d'animation")