Consultez cette page pour apprendre à créer un nouveau composant Scene Graph nommé puzzle_component qui gère une énigme conçue avec des entités Scene Graph. Placez alors un composant puzzle_component sur une entité Scene Graph pour déterminer si une énigme composée d'entités Scene Graph descendantes avec des composants déclenchables spécifiés comme clés d'énigme est résolue.
Par exemple, l'image suivante est une énigme simple que vous concevrez dans la dernière section de ce tutoriel.
L'organiseur correspondant à cette énigme est illustré ci-dessous.
Chaque entité descendante de Prefab_PuzzleManager fait partie de l'énigme gérée par le composant puzzle_component du Prefab_PuzzleManager correspondant. Le composant composant_puzzle :
reçoit des événements lorsque la clé d'une énigme a été activée vers la configuration résolue ;
détermine le moment où l'énigme est résolue ;
envoie des événements dans la hiérarchie Scene Graph lorsque l'énigme est résolue pour déclencher des actions correspondant à la solution.
Lorsque le joueur monte sur les plateformes et allume les deux lumières, le maillage s'anime et se transforme.
Pour en savoir plus sur les fonctionnalités du langage Verse utilisées sur cette page, consultez les rubriques suivantes :
Définir l'événement d'énigme résolue
Pour commencer, accédez à l'explorateur Verse, faites un clic droit sur le nom du projet et choisissez Ajouter un nouveau fichier Verse au projet.
Choisissez le modèle Composant Scene Graph et remplacez le nom du composant par puzzle_component.
Définissez l'événement
puzzle_solved_event. Il s'agit de l'événement transmis via la hiérarchie Scene Graph lorsque l'énigme est résolue pour déclencher une action, par exemple l'ouverture d'une porte ou l'extension d'un pont afin que le joueur puisse se déplacer au-delà de la zone délimitée par l'énigme. Définissez l'événementpuzzle_solved_eventcomme classe enfant descene_event. Cet événement ne nécessite aucun paramètre transmis dans la hiérarchie.Versepuzzle_solved_event<public> := class(scene_event){}
Définir le composant d'énigme
Ensuite, définissez le composant puzzle_component avec des champs et des fonctions pour gérer l'énigme et déterminer si elle est résolue ou non.
Ajoutez des champs pour déterminer si l'énigme est résolue ou non, une matrice des clés de l'énigme qui se trouvent dans la configuration résolue, et indiquez si le déclenchement des clés d'énigme se poursuit ou non après la résolution de l'énigme :
Versepuzzle_component := class<final_super>(component): # Is this puzzle component solved var<private> Solved<public>:logic = false # Map of puzzle pieces and whether they have been "solved" var<private> TriggerableEntities<private>:[]entity = array{} # Disable puzzle pieces triggering once puzzle is solved @editableAjoutez une fonction nommée
InitializeTriggerableDescendantEntitiespour initialiser la liste de toutes les clés d'énigme qui font partie de cette énigme. Cette fonction parcourt la hiérarchie Scene Graph pour trouver toutes les entités déclenchables identifiées comme étant une clé d'énigme et les ajoute à la matriceTriggerableEntities.Verse# Initialize array of triggerable entities InitializeTriggereableDescendantEntities<private>()<transacts>:void= for: DescendantEntity : Entity.FindDescendantEntities(entity) DescendantEntityComponent : DescendantEntity.GetComponents() CastToTriggerable := triggerable[DescendantEntityComponent] CastToTriggerable.PuzzlePiece? do: set TriggerableEntities += array{DescendantEntity}Ajoutez une fonction nommée
DisableTriggerableComponentspour désactiver tous les composants déclenchables sur les entités descendantes.Verse# Disable puzzle pieces DisableTriggerableComponents<private>():void= for: DescendantEntity : Entity.FindDescendantEntities(entity) DescendantEntityComponent : DescendantEntity.GetComponents() CastToTriggerable := triggerable[DescendantEntityComponent] CastToTriggerable.PuzzlePiece? CastToEnableable := enableable[DescendantEntityComponent] do: CastToEnableable.Disable()Ajoutez une fonction nommée
IsPuzzleSolvedqui détermine si l'énigme est dans un état résolu. Pour cela, itérez sur toutes les entités descendantes précédemment trouvées avec un composant qui implémente l'interfacedéclenchable, en vérifiant si l'entité associée est identifiée comme étant une clé d'énigme, et en déterminant si le composant de l'entité qui implémentetriggerableest dans un état résolu.Verse# Decides whether puzzle is solved IsPuzzleSolved<private>()<decides><transacts>:void= for: TriggerableEntity : TriggerableEntities TriggerableEntityComponent : TriggerableEntity.GetComponents() CastToTriggerable := triggerable[TriggerableEntityComponent] CastToTriggerable.PuzzlePiece? do: CastToTriggerable.InSolvedState[]Ajoutez une fonction nommée
HandlePuzzleSolvedpour effectuer toutes les actions nécessaires une fois qu'il est déterminé que l'énigme est résolue. Cela inclut la définition du champRésolusur cette classe, la désactivation des composants déclenchables de l'énigme en fonction du champ de classeDisablePuzzleTriggerablesWhenSolvedet l'envoi de l'événementpuzzle_solved_eventdans la hiérarchie Scene Graph.Verse# Handle all necessary actions once puzzle is known to be solved HandlePuzzleSolved<private>():void= set Solved = true if (DisablePuzzleTriggerablesWhenSolved?): DisableTriggerableComponents() Entity.SendDown(puzzle_solved_event{})Ensuite, ajoutez une fonction nommée
CheckPuzzleSolution. Il s'agit d'une fonction de wrapper asynchrone permettant de déterminer si l'énigme est résolue avecIsPuzzleSolvedet, si c'est le cas, qui appelle égalementHandlePuzzleSolvedpour effectuer les actions nécessaires lorsque l'énigme est résolue.Verse# Async wrapper for determining whether puzzle is solved CheckPuzzleSolved()<suspends>:void= Sleep(0.25) if (not Solved?, IsPuzzleSolved[]): HandlePuzzleSolved()Ajoutez un remplacement pour la fonction
OnReceivede la classe de composant Scene Graph.Verse# Handle triggered events sent through the Scene Graph hierarchy OnReceive<override>(SceneEvent:scene_event):logic= if (TriggeredEvent := triggered_event[SceneEvent], TriggeredEntity := TriggeredEvent.TriggeredEntity?): spawn{CheckPuzzleSolved()} true falseAjoutez un appel à
InitializeTriggerableDescendantEntitiesà la fonctionOnBeginSimulationdu composant.Verse# Runs when the component should start simulating in a running game. OnBeginSimulation<override>():void = # Run OnBeginSimulation from the parent class before # running this component's OnBeginSimulation logic (super:)OnBeginSimulation() InitializeTriggereableDescendantEntities()
Étapes suivantes
Ensuite, créez le composant de déclenchement et les composants déclenchables qui implémentent l'interface déclenchable.
Code final pour Puzzle.verse
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /Verse.org/SceneGraph }
using { Logging }
puzzle_solved_event<public> := class(scene_event){}
# Scene Graph component handling puzzle component triggered events and when the puzzle is solved.
puzzle_component := class<final_super>(component):