Dialogues
Préparation
Créez le répertoire de vos scripts .dlg comme expliqué dans ce tutorial. Nous utiliserons le nom "dlgtutorial". Téléchargez la map de test utilisée pour notre exemple. Il s'agit d'une simple pièce où Aida se tient près d'une porte fermée. Aida utilise le script inert.u2s, un des scripts par défaut fournis avec le jeu, pour ne pas errer dans la map.
Créez un fichier texte vide que vous nommerez aidadialog.dlg et placez-le dans le dossier /Dialog/dlgtutorial. Assurez-vous que votre éditeur de texte n'y ajoute pas une extension .txt. Ce fichier contiendra notre dialogue. Dans UnrealEd, ouvrez les propriétés du niveau en appuyant sur F6 ou en passant par le menu View → Level Properties. Sous LevelInfo, Assurez-vous que la champ MapName contient le même nom que le dossier de dialogues : dlgtutorial.
Le système de dialogues identifie les interlocuteurs en utilisant le nom trouvé dans les propriétés de chaque Pawn. Ouvrez les propriétés d'Aida et, dans l'onglet Dialog, entrez "Aida" dans le champ Speaker. Unreal 2 comparera ce nom à celui des interlocuteurs dans le fichier de la conversation.
Un dialogue pouvant être une arborescence complexe avec plusieurs branches, il peut être utile d'en réaliser un schéma pour pouvoir vérifier quelles branches sont disponibles à chaque instant. Dans notre cas, il s'agit d'un simple choix permettant à Aida de nous ouvrir la porte.
Lorsque l'on s'adresse à elle, Aida demande au joueur si elle peut l'aider. Celui-ci peut lui demander d'ouvrir la porte, auquel cas elle répondra "OK, la porte est ouverte !" et le porte sera déclenchée pour s'ouvrir. Si le joueur ne lui demande rien, elle répondra "Faites-moi signe si besoin."
Premiers nodes
Une conversation est composée de plusieurs nodes. Chaque node contient une ligne de dialogue et ses paramètres : qui la prononce, quelles sont les répliques suivantes, quels sons doivent être joués en même temps, etc. Pour créer le premier node, celui où Aida salue le joueur, ouvrez aidadialog.dlg, qui est actuellement vide, et ajoutez ces lignes :
[AidaDialog]
Speaker=Aida
LongText=Bonjour, comment puis-je vous aider ?
Cela constitue déjà un premier node fonctionnel, même s'il n'est pas encore possible d'adresser la parole à Aida. Passons ces premières lignes en revue :
- [AidaDialog]: Le titre de ce node entre "[]". Tout ce qui est écrit entre ce titre et le prochain "[" est considéré comme faisant partie de ce node.
- Speaker: Personnage qui prononce cette phrase. Dans le cas présent, il s'agit d'Aida. Cette ligne est comparée au contenu du champ Speaker de chaque Pawn. Il existe un Speaker préprogrammé : "Player". Celui-ci se réfère toujours au joueur.
- LongText: La ligne de dialogue. Il s'agit du texte qui s'affiche au bas de l'écran si vous adressez la parole à Aida.
Pour que la conversation soit possible, il faut ajouter quelques lignes au fichier .dlg.
[AidaDialog]
Speaker=Aida
LongText=Bonjour, comment puis-je vous aider ?
NextNode=AidaDialogA[AidaDialogA]
Speaker=Player
ShortText=Ouvrez
LongText=Ouvrez la porte, s'il vous plaît.
Si vous testez la map en jeu, Aida est désormais entourée d'un cadre qui signale qu'une interaction est possible. On peut ainsi entamer la conversation. Voici les nouvelles commandes ajoutées :
- NextNode: Le prochain node dans la conversation. Si le speaker du node suivant n'est pas "Player", le node est joué immédiatement. Si le speaker du node suivant est "Player", le jeu propose le node au joueur en lui montrant le champ ShortText. Une fois que le joueur a choisi la ligne suivante, LongText est utilisé comme sous-titre du joueur.
- ShortText: Texte abrégé servant à proposer la réplique au joueur. Ce champ n'est utile que si le speaker du node est le joueur lui-même. Il s'agit généralement d'une version très condensée de la réplique ou du thème principal de celle-ci.
Conversations
Le dialogue est fonctionnel et il est maintenant possible de parler à Aida. Si vous vous demandez où est spécifiée la discussion en cours, la réponse est simple : nulle part. Lors du chargement de la map, si un dossier de dialogues avec le bon nom existe, Unreal 2 charge tous les fichiers .dlg et garde en mémoire toutes les conversations disponibles. Elles sont immédiatement actives dans le jeu. Si vous parlez à un personnage, le moteur cherche une conversation valide entre le jouer et le PNJ (en regardant les champs Speaker) et s'il en trouve une, c'est le dialogue qui sera utilisé.
Si plusieurs sujets de conversation sont disponibles, le jeu en choisira un au hasard. Il ne s'agira peut-être pas du plus approprié à la situation en cours. Dans le cas présent, ce n'est pas critique car il n'y a qu'une seule discussion possible.
Notre exemple est très simple : le .dlg contient une conversation en deux étapes entre le joueur et Aida. Le jeu sait exactement où le dialogue commence (le premier node du fichier), donc le niveau fonctionne. La plupart des niveaux contiennent plusieurs dialogues et il est donc nécessaire de signaler au jeu les différentes conversations que le joueur peut avoir avec un PNJ. L'inventaire se fait dans le node [Root].
Ajoutez les deux lignes suivantes à aidadialog.dlg :
[Root]
Conversation=AidaDialog[AidaDialog]
Speaker=Aida
LongText=Bonjour, comment puis-je vous aider ?
NextNode=AidaDialogA[AidaDialogA]
Speaker=Player
ShortText=Ouvrez
LongText=Ouvrez la porte, s'il vous plaît.
Le jeu est ainsi conscient qu'il dispose d'une conversation qui commence au node [AidaDialog]. Si vous ajoutez de nouveaux sujets de discussion entre le joueur et Aida, ajoutez des lignes Conversation au node [Root]. Référez-vous aux fichiers .dlg utilisés dans les niveaux à bord de l'Atlantis pour voir comment gérer plusieurs conversations.
Finalisation
Le fichier .dlg ne contient encore que deux des nodes du schéma. Pour compléter le dialogue, le fichier doit ressembler à ceci :
[Root]
Conversation=AidaDialog[AidaDialog]
Speaker=Aida
LongText=Bonjour, comment puis-je vous aider ?
NextNode=AidaDialogA
NextNode=AidaDialogB[AidaDialogA]
Speaker=Player
ShortText=Ouvrez
LongText=Ouvrez la porte, s'il vous plaît.
NextNode=AidaDialog1[AidaDialogB]
Speaker=Player
ShortText=Ça ira
LongText=Tout va bien, merci.
NextNode=AidaDialog2[AidaDialog1]
Speaker=Aida
LongText=OK, la porte est ouverte !
// Fin[AidaDialog2]
Speaker=Aida
LongText=Faites-moi signe si besoin.
// Fin
Le fichier final reste très lisible : Aida salue le joueur et lui donne deux options. Comme le node [AidaDialog] a deux NextNode qui mènent tous les deux à des nodes avec le speaker Player, le jeu propose les deux options au joueur en lui montrant le contenu des champs ShortText. Chacun de ces nodes mène ensuite à une réponse appropriée d'Aida.
Events
Aida accepte d'ouvrir la porte, mais rien ne se passe. Il existe deux manières de déclencher un Event depuis un dialogue : Event et ExitEvent.
- Event: Déclenche un Event après qu'un certain pourcentage de la durée du node se soit écoulé. Si le pourcentage n'est pas spécifié, le déclenchement est immédiat. Une ligne comme "Event=ExampleName" déclenche l'Event "ExampleName" dès que le node commence. "Event=ExampleName,,50" (notez les deux virgules) déclenche l'Event après que 50 % de la durée du node se soit écoulée.
Les pourcentages très élevés ne sont pas fiables et l'Event peut ne pas être déclenché, notamment si le nombre d'images par seconde est bas. Ainsi, "Event=ExampleName,,99" risque d'être sans effet. Un pourcentage inférieur à 90 a moins de chances d'échouer. - ExitEvent: Déclenche un Event à la fin de la conversation. Quand le dialogue contient un ExitEvent, celui-ci est gardé en mémoire et déclenché quand le dialogue se termine. ExitEvent fonctionne de façon fiable et il est donc conseillé quand l'Event est nécessaire.
On utilise donc l'ExitEvent pour qu'Aida ouvre la porte :
[AidaDialog1]
Speaker=Aida
LongText=OK, la porte est ouverte !
ExitEvent=Door
// Fin
L'ExitEvent peut être ajouté au node [AidaDialogA], celui que le joueur choisit pour demander l'ouverture à Aida. Comme il est déclenché à la fin de la conversation entière et non du node, n'importe quel node après que le joueur ait demandé l'ouverture de la porte convient.
SpokenMax
Une fois la conversation terminée, il n'est plus possible d'interagir avec Aida. Si le joueur n'a pas demandé à Aida d'ouvrir, il est impossible de reprendre la discussion pour lui demander de l'aide.
Chaque node du dialogue possède un compteur interne qui détermine combien de fois il peut être activé. Par défaut, ce compteur est à 1 et les nodes ne peuvent donc être lus qu'une seule fois, après quoi ils sont supprimés du jeu. Unreal 2 ne trouve alors plus de dialogue valide à utiliser entre Aida et le joueur et ne permet plus de lui parler. Pour que la conversation puisse avoir lieu à nouveau, on utilise le paramètre SpokenMax.
[Root]
Conversation=AidaDialog[AidaDialog]
Speaker=Aida
SpokenMax=5 // Dialogue jouable 5 fois
LongText=Bonjour, comment puis-je vous aider ?
NextNode=AidaDialogA
NextNode=AidaDialogB
SpokenMax indique combien de fois le node peut être utilisé. Pour que le node reste toujours accessible, on utilise SpokenMax=0.
Activer et désactiver des nodes
Si tous les nodes ont l'attribut SpokenMax=0, il est possible de se retrouver dans une situation où Aida propose au joueur de lui ouvrir la porte alors que celle-ci est déjà ouverte (la porte est réglée sur TriggerOnce et ne se referme jamais). On remédie à ce problème en désactivez le node "Ouvrez" une fois que la tâche est accomplie.
Le node [AidaDialog1] doit être réglé comme suit :
[AidaDialog1]
Speaker=Aida
SpokenMax=0
LongText=OK, la porte est ouverte !
ExitEvent=Door
DisableNode=AidaDialogA // Désactive l'option permettant d'ouvrir
// Fin
Si le joueur s'adresse à Aida et ne lui demande rien, il peut ensuite revenir la voir et lui demander d'ouvrir. Une fois la porte ouverte, le node [AidaDialogA] est désactivé et le joueur ne peut plus répondre qu'avec "Ça ira".
La branche de dialogue peut être masquée sans désactiver le node en question : pour cela, on règle tous les nodes sauf le node "Ouvrez" en SpokenMax=0. "Ouvrez" ne sera utilisable qu'une fois avant d'être supprimé des choix possibles, comme c'est le cas par défaut. Lors des prochaines conversation avec Aida, seul le choix "Ça ira" sera sélectionnable.
Il existe une commande inverse de DisableNode : EnableNode. Elle perme d'activer un node qui n'est pas disponible. Par défaut, tous les nodes sont considérés comme actifs, mais on peut choisir de les désactiver au lancement du jeu en ajoutant la ligne Enabled=false.
Dialogues et scripts
Dans un script, la commande dialoginitiate permet de forcer un PNJ à entamer lui-même la conversation, sans attendre d'être activé.
Dialoginitiate [Interlocuteur] (Node) pousse le PNJ à adresser la parole au personnage dont le champ Speaker correspond au paramètre [Interlocuteur]. Si ce paramètre est vierge, le PNJ s'adresse au joueur.
Les nodes peuvent aussi être activés et désactivés dans un script .u2s :
dialogenable (Node)
dialogdisable (Node)
Autres options
Un aspect non couvert par ce tutorial est l'utilisation de la commande SoundFile. Elle est facile d'utilisation et un rapide coup d'œil aux fichiers .dlg du jeu original (où tous les dialogues sont audibles) permet de comprendre son fonctionnement. La commande SoundFile peut faire appel à des fichiers .ogg (dans le dossier /Voice) ou à des fichiers .wav (rassemblés dans des fichiers .uax, dans le dossier /Sounds).
De nombreuses autres options sont disponibles pour enrichir un node, mais ce tutorial ne couvre que l'essentiel.
Si un PNJ possède plus d'un sujet de conversation (ceux-ci sont listés dans le node [Root] avec une ligne Conversation chacun), il est préférable de s'assurer qu'un seul thème est actif à la fois. Dans le cas contraire, le jeu choisit aléatoirement une des conversations quand le dialogue commence. Il faut donc désactiver les premiers nodes de toutes les conversations, sauf pour celle que l'on souhaite garder active. L'activation des conversations se fait ensuite par script au fur et à mesure que le joueur avance dans la map.
Narrateur invisible
Un narrateur invisible peut être simulé en créant un dialogue factice entre le joueur et lui-même. Il est déclenché en activant un interlocuteur invisible
Créez un nouveau fichier de dialogue pour le narrateur et ajoutez une chaîne de nodes se suivant linéairement, en vous assurant que Speaker est toujours réglé sur Player. Chaque node reçoit ensuite la commande HideChoices=true qui permet aux différents nodes de se succéder sans demander au joueur de choisir la réplique suivante.
Si un enregistrement audio du dialogue est utilisé, chaque commande SoundFile doit se finir par le paramètre ",Player". Il permet au son d'être joué à son volume maximal quelle que soit la distance entre les participants au dialogue.
Créez un script .u2s contenant la commande "dialogfar" avec deux arguments : le nom de la conversation qui contient la narration et la personne à qui ce dialogue s'adresse : player.
Ajoutez un LevelMaster à votre map (Pawn LicenseePawn → U2Pawn → U2PawnBase → LevelMaster). Il servira à déclencher la conversation. Dans ses propriétés, entrez le nom du script .u2s dans AI → CommandFileName.
Pour lancer la narration, il suffit alors d'utiliser un Trigger pour déclencher le LevelMaster en cours de jeu.
Un bon exemple se trouve dans la map CS_Outro, qui contient la cinématique de fin du jeu. Le LevelMaster a pour CommandFileName CS_OutroDialog. Le script CS_OutroDialog.u2s contient la commande :
dialogfar DorianGray_04_002 player
Le fichier de dialogue lié à cette map contient une seule conversation, la narration, référencée au début du fichier :
[Root]
Conversation=DorianGray_04_002
RSS Feed