Esta página orienta você na criação de um novo componente do Scene Graph chamado puzzle_component, que gerencia um quebra-cabeça construído com entidades do Scene Graph. Depois de criado, coloque um puzzle_component em uma entidade do Scene Graph para determinar se um quebra-cabeça que consiste de entidades descendentes do Scene Graph com componentes acionáveis especificados como peças de quebra-cabeça foi resolvido.
Por exemplo, a imagem a seguir mostra um quebra-cabeça simples que você construirá na última seção deste tutorial.
O Organizador correspondente a esse quebra-cabeça é mostrado na próxima imagem.
Cada entidade descendente de Prefab_PuzzleManager faz parte do quebra-cabeça gerenciado pelo puzzle_component correspondente do Prefab_PuzzleManager. O puzzle_component:
Recebe eventos quando uma peça de quebra-cabeça é trocada para a configuração resolvida.
Determina quando o quebra-cabeça é resolvido.
Envia eventos para baixo na hierarquia do Scene Graph quando o quebra-cabeça é resolvido para acionar ações correspondentes à solução.
Quando o jogador pisa nas plataformas e acende as duas luzes, a malha é animada e transformada.
Para obter mais informações sobre as funcionalidades da linguagem Verse usadas nesta página, consulte:
Defina o evento "Quebra-cabeça resolvido"
Para começar, acesse o Explorador Verse, clique com o botão direito do mouse no nome do projeto e escolha Adicionar novo arquivo Verse ao projeto.
Escolha o modelo Componente do Scene Graph e altere o Nome do Componente para puzzle_component.
Defina
puzzle_solved_event. Este é o evento transmitido pela hierarquia do Scene Graph quando o quebra-cabeça é resolvido para acionar uma ação, como abrir um portão ou estender uma ponte, para que o jogador possa se mover além da área bloqueada pelo quebra-cabeça. Definapuzzle_solved_eventcomo uma classe filha descene_event. Esse evento não requer nenhum parâmetro transmitido na hierarquia.Versepuzzle_solved_event<public> := class(scene_event){}
Defina o componente quebra-cabeça
Em seguida, defina o puzzle_component com campos e funções para gerenciar o quebra-cabeça e se ele foi resolvido ou não.
Adicione campos para rastrear se o quebra-cabeça foi resolvido ou não, uma matriz de quais peças do quebra-cabeça estão na configuração resolvida e se as peças do quebra-cabeça continuam ou não acionáveis após a resolução do quebra-cabeça:
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 @editableAdicione uma função chamada
InitializeTriggerableDescendantEntitiespara inicializar a lista de todas as peças que fazem parte desse quebra-cabeça. Essa função percorre a hierarquia do Scene Graph para encontrar todas as entidades acionáveis marcadas como sendo uma peça de quebra-cabeça e as adiciona à 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}Adicione uma função chamada
DisableTriggerableComponentspara desabilitar componentes acionáveis em entidades descendentes.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()Adicione uma função chamada
IsPuzzleSolvedque decide se o quebra-cabeça está em um estado resolvido. Isso é feito iterando todas as entidades descendentes encontradas anteriormente com um componente que implementa a interfacetriggerable, verificando se a entidade associada está marcada como uma peça do quebra-cabeça e se o componente da entidade que implementatriggerableestá em um estado resolvido.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[]Adicione uma função chamada
HandlePuzzleSolvedpara executar todas as ações necessárias quando for determinado que o quebra-cabeça foi resolvido. Isso inclui definir o campoSolvednessa classe, desabilitar os itens acionáveis do quebra-cabeça com base no campo da classeDisablePuzzleTriggerablesWhenSolvede enviar opuzzle_solved_eventpara baixo na hierarquia do 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{})Em seguida, adicione uma função chamada
CheckPuzzleSolution. Esta é uma função agrupadora assíncrona para determinar se o quebra-cabeça foi resolvido comIsPuzzleSolvede, se for, também chamaHandlePuzzleSolvedpara executar as ações necessárias quando o quebra-cabeça for resolvido.Verse# Async wrapper for determining whether puzzle is solved CheckPuzzleSolved()<suspends>:void= Sleep(0.25) if (not Solved?, IsPuzzleSolved[]): HandlePuzzleSolved()Adicione uma substituição para a função
OnReceiveda classe de componente do 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 falseAdicione uma chamada para
InitializeTriggerableDescendantEntitiesà funçãoOnBeginSimulationdo 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óximas etapas
Em seguida, crie o componente de gatilho e os componentes acionáveis que implementam a interface acionável.
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):