Esta página te guía a través de la creación de un nuevo componente de Scene Graph denominado puzzle_component que gestiona un rompecabezas creado con entidades de Scene Graph. Una vez construido, coloca un puzzle_component en una entidad de Scene Graph para determinar si se resuelve un rompecabezas formado por entidades descendientes de Scene Graph con componentes activables que se especifican como piezas del rompecabezas.
Por ejemplo, la siguiente imagen es un rompecabezas sencillo que construirás en la última sección de este tutorial.
El esquematizador correspondiente a este rompecabezas se muestra en la siguiente imagen.
Cada entidad descendiente de Prefab_PuzzleManager forma parte del rompecabezas gestionado por el puzzle_component correspondiente de Prefab_PuzzleManager. puzzle_component:
Recibe eventos cuando una pieza del rompecabezas ha cambiado a la configuración resuelta.
Determina cuándo se resuelve el rompecabezas.
Envía eventos a la jerarquía de Scene Graph cuando se resuelve el rompecabezas para activar las acciones correspondientes a la solución.
Cuando el jugador pisa las plataformas y enciende las dos luces, la malla se anima y se transforma.
Para obtener más información sobre las funciones del lenguaje Verse utilizadas en esta página, consulta:
Cómo definir el evento de rompecabezas resuelto
Para empezar, ve al Explorador de Verse, haz clic con el botón derecho en el nombre del proyecto y elige Añadir nuevo archivo de Verse al proyecto.
Elige la plantilla componente de Scene Graph y cambia el nombre del componente a puzzle_component.
Define
puzzle_solved_event. Este es el evento que se transmite a través de la jerarquía de Scene Graph cuando se resuelve el rompecabezas para que se active una acción, como abrir una puerta o ampliar un puente para que el jugador pueda moverse más allá de la zona delimitada por el rompecabezas. Definepuzzle_solved_eventcomo una clase hijo descene_event. Este evento no requiere que se pase ningún parámetro a los descendientes de la jerarquía.Versepuzzle_solved_event<public> := class(scene_event){}
Cómo definir el componente del rompecabezas
A continuación, define el puzzle_component con campos y funciones para gestionar el rompecabezas y si se resuelve o no.
Añadir campos para controlar si el rompecabezas se resuelve o no, una matriz de las piezas del rompecabezas que están en la configuración resuelta y si las piezas siguen activándose después de resolver el rompecabezas:
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 @editableAñade una función denominada
InitializeTriggerableDescendantEntitiespara inicializar la lista de todas las piezas del rompecabezas que forman parte de él. Esta función recorre la jerarquía de Scene Graph para encontrar todas las entidades activables marcadas como pieza del rompecabezas y las añade a la matrizTriggerableEntities.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}Añade una función denominada
DisableTriggerableComponentspara desactivar cualquier componente activable en las entidades descendientes.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()Añade una función denominada
IsPuzzleSolvedque decida si el rompecabezas está resuelto. Esto se hace iterando a través de todas las entidades descendientes encontradas previamente con un componente que implemente la interfazactivable, comprobando si la entidad asociada está marcada como pieza del rompecabezas y si el componente de la entidad que implementaactivadorse encuentra en un estado resuelto.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[]Añade una función denominada
HandlePuzzleSolvedpara realizar todas las acciones necesarias una vez que se determine que el rompecabezas está resuelto. Esto incluye establecer el campoResueltoen esta clase, deshabilitar los activadores de rompecabezas en función del campo de la claseDisablePuzzleTriggerablesWhenSolvedy enviar elpuzzle_solved_eventhacia abajo en la jerarquía de 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{})A continuación, añade una función nombrada
CheckPuzzleSolution. Se trata de una función envoltorio asíncrona que determina si el rompecabezas se resuelve conIsPuzzleResueltoy, si lo es, también llama aHandlePuzzleSolvedpara realizar las acciones necesarias cuando se resuelva el rompecabezas.Verse# Async wrapper for determining whether puzzle is solved CheckPuzzleSolved()<suspends>:void= Sleep(0.25) if (not Solved?, IsPuzzleSolved[]): HandlePuzzleSolved()Añade una anulación para la función
OnReceivede la clase del componente 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 falseAñade una llamada a
InitializeTriggerableDescendantEntitiesa la funciónOnBeginSimulationdel componente.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()
Siguientes pasos
A continuación, crea los componentes activadores y los componentes activables que implementan la interfaz.
Código final para 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):