Conditions¶
Une condition est un petit Blueprint (ou une classe C++) réutilisable qui évalue une situation et répond à une unique question par oui ou non au runtime. Questions typiques :
- Le joueur a-t-il déjà parlé à ce personnage ?
- A-t-il trouvé telle pièce d'un puzzle ?
- Son personnage possède-t-il assez d'une certaine compétence ?
Les conditions sont le ciment qui rend les dialogues réactifs. Dans le Dialogue Editor, elles verrouillent les lignes de Reply, les branches If / ElseIf et des subdialogues entiers — mais la même classe est tout aussi utilisable depuis n'importe quel Blueprint (interactions, triggers, logique de gameplay).
Ce qu'est une condition¶
La classe de base de toute condition est ULBRCondition (module LBRConditions). Pour créer la
vôtre, dérivez-en — ou d'une classe qui en dérive déjà — et implémentez la logique d'évaluation.
Tip
De nombreux besoins sont déjà couverts par les conditions prêtes à l'emploi bâties sur le système des GPVars — vérifiez-les avant d'écrire une nouvelle classe. Voir GPVars & Conditions.
ULBRCondition est marquée Abstract, Blueprintable, DefaultToInstanced et EditInlineNew, si
bien que vous pouvez la sous-classer en Blueprint et qu'elle est destinée à être instanciée partout
où elle est utilisée (plus de détails sous Conditions instanciées).
Écrire une condition¶
Surchargez Evaluate — un BlueprintNativeEvent qui renvoie le résultat du test. En Blueprint,
vous implémentez l'événement Evaluate ; en C++, vous surchargez Evaluate_Implementation(). La
déclaration de base est purement virtuelle, si bien que toute condition concrète doit en fournir une.
// C++ signature to override
virtual bool Evaluate_Implementation() override;

Evaluate ne prend aucun paramètre et renvoie un bool. Elle est protected : les appelants ne
l'invoquent pas directement — ils passent par EvaluateWithCache, qui
décide s'il faut exécuter Evaluate ou non.
Libellés dans l'éditeur¶
Pour qu'une condition se lise clairement dans le Dialogue Editor, surchargez les hooks de libellé. Ils font apparaître une courte description sur la ligne qui porte la condition :
| Override | Affiché sur |
|---|---|
GetLabel |
La ligne Reply (le libellé générique). |
GetLabelSuccess |
La ligne If (ce que signifie la branche de succès). |
GetLabelFail |
La ligne Else (ce que signifie la branche d'échec). |
Chacun est un BlueprintNativeEvent renvoyant un FText ; par défaut, ils renvoient un texte vide.
Opérateurs intégrés¶
LBRConditions fournit des conditions opérateurs composables afin que vous puissiez construire des
expressions sans écrire de code. Chacune prend d'autres conditions comme opérandes (instanciés) :
| Condition | Nom d'affichage | Résultat |
|---|---|---|
ULBRConditionAnd |
AND | vrai lorsque tous les opérandes sont vrais |
ULBRConditionOr |
OR | vrai lorsque au moins un opérande est vrai |
ULBRConditionXOr |
XOR | vrai lorsque exactement un opérande est vrai |
ULBRConditionNot |
NOT | inverse son unique Condition |
ULBRConditionFalse |
FALSE | toujours faux |
ULBRConditionEmpty |
— | toujours vrai (la condition neutre) |

Le cache succès/échec¶
Évaluer une condition peut être coûteux, et la même condition peut être vérifiée à répétition. Chaque
ULBRCondition peut donc mémoriser son résultat d'évaluation et éviter de ré-exécuter Evaluate. Le
résultat est rangé dans l'historique des conditions, qui est global : il
survit aux changements de niveau et peut être sauvegardé.
Deux flags, situés dans la section advanced de la propriété, activent la mise en cache :
| Flag | Effet |
|---|---|
bCacheSuccess |
Une fois que la condition s'évalue à true, ce résultat est mis en cache et réutilisé — plus aucune vérification. |
bCacheFailure |
Une fois que la condition s'évalue à false, ce résultat est mis en cache et réutilisé. |
Activez l'un, l'autre, ou les deux. Les deux valent false par défaut (toujours ré-évaluer).

Warning
La mise en cache suppose que la réponse ne changera pas. Ne l'activez que pour des conditions dont le résultat est stable une fois atteint (par exemple, « le joueur a terminé le tutoriel ») — faute de quoi la valeur périmée en cache sera servie indéfiniment.
Appeler une condition depuis un Blueprint¶
Depuis n'importe quel Blueprint, vérifiez que la condition est valide, puis appelez
EvaluateWithCache :
- Avec
bForceEvaluation = false(la valeur par défaut), elle renvoie le résultat en cache lorsqu'il est valide, sinon elle exécuteEvaluate, met le résultat en cache si le flag pertinent est activé, et le renvoie. - Avec
bForceEvaluation = true, elle ignore le cache et exécute toujoursEvaluate.

Trois helpers vous permettent d'inspecter et de gérer le cache manuellement :
| Fonction | Rôle |
|---|---|
IsStoredResultValid() |
Renvoie false si la condition n'a jamais été évaluée, a été invalidée, ou si ses flags de cache ne couvrent plus le résultat mémorisé. |
GetStoredResult() |
Renvoie le résultat mémorisé (sans évaluer), ou false s'il n'y a pas de résultat mémorisé valide. |
InvalidateLastResult() |
Retire le résultat mémorisé de l'historique pour que le prochain EvaluateWithCache ré-exécute Evaluate. |
L'historique des conditions¶
Les résultats en cache vivent dans ULBRConditionHistorySubsystem, un engine subsystem : un
registre global pour toute la session de jeu, avec la même durée de vie que les GPVars. Chaque entrée
a pour clé le chemin du sous-objet condition, et ce registre est la seule source du cache : une
condition ne garde aucun résultat de son côté. Dans l'éditeur, l'historique est vidé au début et à la
fin de chaque session PIE.
Un résultat mémorisé n'est utilisé que tant que les flags de la condition le couvrent : si vous
décochez bCacheSuccess sur une condition, son true mémorisé est ignoré et la condition est
réévaluée.
Depuis un Blueprint :
| Fonction | Rôle |
|---|---|
Add(Path, bResult) |
Mémorise un résultat pour un chemin. |
Remove(Path) |
Retire l'entrée d'un chemin. |
CheckHistory(Path) |
1 = vrai mémorisé, 0 = faux mémorisé, -1 = aucune entrée. Un false mémorisé ne se confond jamais avec une entrée absente. |
ClearConditionsOf(Owner) |
Retire les entrées de toutes les conditions contenues dans Owner (un dialogue, un acteur, un package). Purger D_Foo laisse D_Foo2 intact. |
ClearAll() |
Vide l'historique. |
En C++, FindConditionResult(Path, bOutResult) renvoie false s'il n'y a pas d'entrée ; bOutResult
n'a de sens que si elle renvoie true.
Pour sauvegarder l'historique, sérialisez le subsystem avec une archive SaveGame, en plus de
ULBRGPVarSubsystem. Charger une sauvegarde remplace tout l'historique.
Piège
L'historique est global et rien n'est purgé automatiquement, pas même au déchargement
d'un niveau : le plugin ne peut pas savoir si une condition doit rester figée quand le joueur
revient. Les résultats des conditions portées par des acteurs de niveau s'accumulent donc tant
que vous ne les purgez pas. Appelez ClearConditionsOf (ou ClearAll) sur ce dont vous n'avez
plus besoin.
Piège
La clé est le chemin de la condition. Renommer ou déplacer un asset perd l'historique de ses conditions. Il n'y a pas de redirect.
Conditions instanciées & ConditionContainer¶
Une condition est un UObject, si bien qu'une propriété qui se contente de la référencer est nulle
jusqu'à ce que vous lui assigniez une instance. Il existe deux façons d'obtenir une condition qui crée
et possède son instance automatiquement.
1 — le spécificateur Instanced (C++). Marquez une propriété ULBRCondition* comme Instanced et
l'éditeur vous laissera choisir une sous-classe et l'éditer en ligne, en créant le sous-objet pour vous :
UPROPERTY(EditAnywhere, BlueprintReadWrite, Instanced, Category = "Conditions")
TObjectPtr<ULBRCondition> MyCondition;
C'est exactement ainsi que les conditions opérateurs contiennent leurs opérandes
(ULBRConditionOperator::Operands, ULBRConditionNot::Condition).
2 — FLBRConditionContainer (aucun C++ requis). Pour le cas courant, utilisez le type de struct
prêt à l'emploi — une fine enveloppe dont l'unique champ Condition est déjà configuré comme
Instanced :
USTRUCT(BlueprintType)
struct FLBRConditionContainer
{
UPROPERTY(EditAnywhere, BlueprintReadWrite, Instanced, Category = "Conditions")
TObjectPtr<ULBRCondition> Condition;
};
Exposez une propriété FLBRConditionContainer et vous obtenez l'édition de condition en ligne dans le
details panel, prête à l'emploi.

Conditions sur les lignes de dialogue¶
Dans le Dialogue Editor, les conditions apparaissent à trois endroits :
- Les lignes de Reply portent deux conditions :
- Display Condition — si fausse, la Reply n'est ni proposée ni affichée.
- Availability Condition — si fausse, la Reply est affichée mais grisée et non sélectionnable.
- Les lignes If / ElseIf utilisent une Success Condition — si vraie, le joueur entre dans cette
branche ; sinon le
ElseIf/Elsesuivant est évalué. - Les Subdialogues portent une Condition qui autorise, ou non, le subdialogue à se jouer. À l'entrée, les subdialogues candidats sont évalués dans l'ordre et le premier dont le nom correspond et dont la condition passe est joué.

Les overrides GetLabel / GetLabelSuccess / GetLabelFail décrits ci-dessus sont ce qui affiche un
résumé lisible directement sur ces lignes. Voir la page Dialogue
Editor pour le workflow d'écriture.
Vérifications « dialogue joué »
Pour tester « ce dialogue/subdialogue a-t-il été joué », utilisez la condition dédiée
ULBRDialogueDoneCondition (dans LBRCore) plutôt qu'une condition sur chemin de GPVar écrite à
la main. Une variante comptée, ULBRDialogueDoneCountedCondition, compare combien de fois un
dialogue ou un subdialogue a été joué. Voir GPVars & Conditions.