Esta página te guía a través de la creación de un nuevo componente de Scene Graph llamado puzzle_component que gestiona un rompecabezas construido 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 que se pueden activar y que se especifican como piezas.
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 del Prefab_PuzzleManager es parte del rompecabezas gestionado por el puzzle_component correspondiente del Prefab_PuzzleManager. El puzzle_component:
Recibe eventos cuando una pieza del rompecabezas se cambia 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 acciones correspondientes a la solución.
Cuando el jugador sube a las plataformas y enciende las luces, la malla se anima y transforma.
Para obtener más información sobre las funciones del lenguaje de Verse utilizadas en esta página, consulta lo siguiente:
Define el evento de rompecabezas resuelto
Para empezar, ve al explorador de Verse, haz clic derecho en el nombre del proyecto y elige Añadir nuevo archivo de Verse al proyecto.
Elige la plantilla de componente de Scene Graph y cambia el nombre del componente a puzzle_component.
Define el
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 activar una acción, como abrir una puerta o extender un puente para que el jugador pueda moverse más allá del área delimitada por el rompecabezas. Define elpuzzle_solved_eventcomo una clase derivada delscene_event. Este evento no requiere que se transmita ningún parámetro a los descendientes de la jerarquía.Versepuzzle_solved_event<public> := class(scene_event){}
Define el Puzzle Component
A continuación, define el puzzle_component con campos y funciones para gestionar el rompecabezas y si se resuelve o no.
Añade campos para rastrear si el rompecabezas se resolvió o no, una matriz de las piezas del rompecabezas que están en la configuración resuelta, y si las piezas del rompecabezas continúan activándose después de que se resuelve el rompecabezas o no:
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 este rompecabezas. Esta función recorre la jerarquía de Scene Graph para encontrar todas las entidades que se pueden activar marcadas como piezas de 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 deshabilitar los componentes que se pueden activar 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 llamada
IsPuzzleSolvedque decida si el rompecabezas está en un estado resuelto. Esto se hace iterando a través de todas las entidades descendientes encontradas anteriormente con un componente que implementa la interfazque se puede activar, al verificar si la entidad asociada está marcada como pieza del rompecabezas, y si el componente de la entidad que implementa la interfazque se puede activarestá 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 se resolvió el rompecabezas. Esto incluye establecer el campoResueltoen esta clase, deshabilitar los activadores de rompecabezas en función del campo de 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 llamada
CheckPuzzleSolution. Esta es una función contenedora asíncrona para determinar si el rompecabezas se resolvió conIsPuzzleSolvedy, si es así, también llama aHandlePuzzleSolvedpara realizar las acciones necesarias cuando se resuelve 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 de componente de 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()
Próximos pasos
A continuación, crea el Trigger Component y los componentes que se pueden activar que implementan la interfaz que se puede activar.
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):