Aller au contenu

Widgets de choix

Lorsqu'un dialogue atteint une ligne Choice, Libretto instancie un widget d'interface qui présente au joueur les réponses disponibles, attend une sélection (ou l'expiration du minuteur du choix), puis saute vers la réponse retenue. Cette page explique comment configurer le widget utilisé et comment créer le vôtre.

Configuration

La classe de widget utilisée par défaut pour les choix de dialogue se définit dans Project Settings ▸ Libretto, dans la section UI.

Choice widget settings in Project Settings ▸ Libretto

  • Widget Choice Default Class — le widget de choix instancié pour un Choice qui ne porte aucun flag correspondant. Si vous le laissez vide, les choix se rabattent sur le widget fourni avec le plugin, DefaultLBRDialogueChoiceWidget_WBP. Ce widget par défaut constitue un bon point de départ : dupliquez-le pour vous en servir de base ou d'exemple concret.
  • Widget Choice Map Class — vous permet de choisir un widget différent pour certains choix, en fonction d'un flag de gameplay présent sur la ligne Choice. L'ordre des entrées de la map définit la priorité : lorsqu'une ligne porte plusieurs flags, le premier flag qui apparaît dans la map détermine la classe de widget utilisée.

Réponses disponibles

Une réponse est considérée comme disponible lorsque toutes les conditions suivantes sont réunies :

  1. Elle n'a jamais été sélectionnée, ou elle l'a été mais Do Once est décoché.
  2. Elle n'a pas de Display Condition, ou la condition s'évalue à true.
  3. Elle n'a pas d'Availability Condition, ou la condition s'évalue à true.

Note

Display Condition et Availability Condition diffèrent par la manière dont une condition non satisfaite est traitée. Une Display Condition non satisfaite retire entièrement la réponse — elle n'est ni proposée ni affichée. Une Availability Condition non satisfaite affiche tout de même la réponse, mais grisée et non sélectionnable. Consultez la page Dialogue Editor pour savoir où définir Do Once, Default Reply et les deux conditions sur une ligne Reply.

Créer un widget personnalisé

Une interface de choix se compose de deux widgets :

  1. Le widget de choix lui-même, qui doit hériter de ULBRDialogueChoiceWidget.
  2. Le widget de bouton de réponse, qui doit hériter de ULBRDialogueChoiceButton.

Propriétés de ULBRDialogueChoiceWidget

Propriété Rôle
Dialogue L'asset Dialogue auquel le choix appartient.
DialogueInstance L'ALBRDialogueInstance en cours d'exécution.
LineIDChoice L'ID de la ligne Choice affichée.
ButtonClass La sous-classe ULBRDialogueChoiceButton utilisée pour les boutons de réponse. Laissez-la vide pour utiliser le bouton par défaut intégré, qui construit à la volée un simple bouton avec texte.
ChoiceTimerHandle Le handle du minuteur pour un choix chronométré — lisez-le pour connaître le temps restant.
ChoiceButtons Les boutons de réponse actuellement instanciés par ce widget.

Ensemble, Dialogue, DialogueInstance et LineIDChoice vous donnent tout ce qu'il faut pour configurer la présentation du choix.

Retrouver l'ID de la ligne Reply à partir d'un IDToJump

Plusieurs méthodes renvoient un IDToJump — l'ID de la première ligne jouée lorsqu'une réponse est retenue, et non l'ID de la ligne Reply elle-même. Pour retrouver l'ID de la ligne Reply à partir d'un IDToJump, appelez Dialogue->GetIndex(IDToJump) pour obtenir l'index de la ligne, puis Dialogue->GetParentIndex(that index) ; l'index parent correspond à la ligne Reply.

Méthodes de ULBRDialogueChoiceWidget

Les méthodes marquées Overridable sont des BlueprintNativeEvent — redéfinissez-les dans le Blueprint de votre widget pour changer le comportement, et appelez la méthode parente lorsque vous souhaitez conserver le comportement par défaut. Les autres sont des utilitaires que vous appelez mais que vous ne devriez pas avoir à réimplémenter.

Méthode Overridable Rôle Comportement par défaut
AddChoiceToView Oui Initialise et affiche le widget. Ajoute le widget à l'écran du joueur, bascule l'entrée en UI only et affiche le curseur de la souris.
AddButtonChoiceToView Oui Appelée après la création de chaque bouton de réponse, pour le rattacher au widget de choix. Ajoute le bouton de réponse comme enfant du panneau racine du widget de choix.
ChoiceTimedOut Oui Appelée par le Dialogue Manager lorsqu'un choix chronométré arrive à échéance. Doit appeler ValidateChoice pour confirmer la sélection. Valide la ligne de choix elle-même, qui se résout en GetChoiceDefaultReplyOrFirstID.
ChoiceSelected Oui Appelée par un bouton de réponse (via ButtonChoiceSelected) lorsque le joueur retient une réponse. Doit appeler ValidateChoice. Utilisez-la pour exécuter des effets de gameplay et pour distinguer un choix explicite du repli sur le défaut à l'expiration du minuteur. Valide la réponse sélectionnée.
ChoiceValidated Oui L'étape finale de validation, appelée une fois qu'une réponse est confirmée. Appelle RemoveWidgetChoice.
RemoveWidgetChoice Oui Démantèle le widget. Rebascule l'entrée en game only, masque le curseur de la souris et retire le widget de son parent.
DisplayChoice Non Appelée par le Dialogue Manager lors de la création du widget de choix. Définit Dialogue, DialogueInstance et LineIDChoice, puis appelle AddChoiceButtons.
AddChoiceButtons Non Appelée par DisplayChoice. Parcourt les réponses du choix et ajoute un bouton de réponse pour chacune des réponses disponibles (les boutons dont l'Availability Condition vaut false sont tout de même ajoutés afin de pouvoir être grisés).
GetChoiceDefaultReplyOrFirstID Non Renvoie l'IDToJump de la première Default Reply disponible, ou de la première réponse disponible, ou -1 si aucune n'est disponible. Parcourt les réponses dans l'ordre : renvoie la première réponse disponible marquée Default Reply ; sinon, la première réponse disponible.
GetChoiceDefaultReplyID Non Renvoie l'IDToJump de la première Default Reply disponible, ou -1. Parcourt les réponses dans l'ordre : renvoie la première réponse disponible marquée Default Reply.

La validation se déroule en deux étapes

ChoiceValidated est le hook de confirmation, et il délègue le démantèlement effectif de l'interface à la méthode distincte et redéfinissable RemoveWidgetChoice. Redéfinissez RemoveWidgetChoice si vous voulez uniquement modifier la façon dont le widget est refermé (mode d'entrée, curseur, animations), et ChoiceValidated si vous devez exécuter de la logique au moment où une réponse est confirmée.

Les choix vides ne provoquent pas de blocage

Un choix peut se retrouver sans aucune réponse sélectionnable (par exemple lorsque, à un second passage, chaque réponse Do Once a déjà été utilisée). Libretto détecte ce cas : le cadre vide est normalement ignoré en amont, et si un widget de choix vide est malgré tout atteint, le dialogue se termine proprement au lieu de boucler. Vous n'avez pas à gérer ce cas dans votre widget.

Propriétés de ULBRDialogueChoiceButton

Propriété Rôle
Dialogue L'asset Dialogue, utilisé pour retrouver la réponse que ce bouton propose.
LineID L'ID de la ligne Reply (son texte d'invite).
LineIDReply L'IDToJump de la réponse — la première ligne jouée lorsque cette réponse est sélectionnée.
ButtonChoiceSelected L'événement que le widget de choix écoute ; il est lié au ChoiceSelected du widget.

Méthodes de ULBRDialogueChoiceButton

Méthode Overridable Rôle Comportement par défaut
ReplySelected Non Appelée lorsque le bouton est cliqué. Diffuse ButtonChoiceSelected avec IDToJump = LineIDReply.
GetReplyText Non Utilisée pour afficher le libellé du bouton. Renvoie le texte localisé de la ligne Reply correspondante.
IsReplyAvailable Non Utilisée pour activer ou désactiver le bouton. Renvoie la disponibilité de la réponse.

Ne pas bloquer le personnage (choix à la Firewatch)

Par défaut, le widget de choix prend le contrôle total : l'entrée passe en UI only et le curseur de la souris apparaît, ce qui empêche le joueur de se déplacer. Si vous voulez un choix que le joueur peut retenir tout en continuant à se déplacer — le style « walk-and-talk » des jeux comme Firewatch —, suivez le motif implémenté dans le widget par défaut fourni.

Dans les grandes lignes :

  • Redéfinissez AddChoiceToView pour qu'il ne bascule pas l'entrée en UI only et ne bloque pas le personnage. Conservez l'entrée de jeu active et ajoutez l'interface de choix en superposition.
  • Ajoutez des liaisons d'entrée pour déplacer le focus d'une réponse à l'autre (et pour en confirmer une) au lieu de vous reposer sur les clics de souris.

Marquer un choix non bloquant

Un flag de gameplay dédié, Libretto.Flags.Choice.NonBlocking, marque une ligne Choice comme non bloquante. Placez-le sur la ligne Choice et associez-le à votre widget walk-and-talk via Widget Choice Map Class. Le widget de base C++ n'agit pas de lui-même sur ce flag — le comportement non bloquant réside dans les redéfinitions de votre widget.