Você pode usar o dispositivo Temporizador, que executa um temporizador de contagem regressiva, mas criando seu próprio temporizador de contagem regressiva em Verse é uma maneira de personalizar o comportamento dele para se adequar exatamente ao que você precisa.
Este tutorial mostrará como criar seu próprio temporizador com Verse e usar um texto explicativo quando o tempo for adicionado à contagem regressiva. Começando de forma simples, você encontrará maneiras de melhorá-lo em cada um dos projetos.
Funcionalidades da linguagem Verse usadas
if: a expressão
iftesta condições e acessa valores que podem falhar.block: este exemplo usa a expressão
blockpara inicializar a interface de usuário quando o temporizador de contagem regressiva é criado.loop: a expressão
loopatualiza a interface de usuário e termina quando a contagem regressiva chega a zero.spawn: uma expressão
spawninicia uma expressão assíncrona em qualquer contexto.message: o tipo "message" significa que o texto pode ser localizado, e a string que você usa para inicializar uma variável "message" é o texto e o idioma padrão da mensagem.
classe: este exemplo cria uma classe Verse que gerencia e exibe a contagem regressiva.
constructor: um "constructor" é uma função especial que cria uma instância da classe à qual ele está associado.
Especificadores de acesso: Você pode usar os especificadores de acesso para definir o nível de acesso do código.
APIs Verse usadas
Sleep: Com a API
Sleep(), você pode escolher o período entre as atualizações da interface de usuário.Events: Você pode criar seus próprios eventos em Verse e adicionar funcionalidades personalizadas quando eles ocorrerem.
Interface de usuário em Verse: Crie uma interface de usuário personalizada no jogo para exibir informações sobre o jogador e o jogo.
Instruções
Siga estas etapas para aprender a criar o próprio temporizador personalizado. O código completo está incluído no final deste guia como referência.
Como configurar o nível
Este exemplo usa os seguintes adereços e dispositivos:
1 dispositivo Botão: quando o jogador interage com o dispositivo, mais tempo é adicionado à contagem regressiva.
1 dispositivo Fim de Jogo: quando a contagem regressiva termina, esse dispositivo faz com que o jogo termine.
Siga estas etapas para configurar o nível:
Adicione um dispositivo Botão e um dispositivo Fim de Jogo ao nível.
Crie um novo dispositivo Verse chamado
countdown_timer_exampleusando o Explorador Verse. Consulte os passos em Crie seu próprio dispositivo usando o Verse.Adicione uma referência editável ao dispositivo Botão em
countdown_timer_examplechamadaAddMoreTimeButton. Consulte as etapas necessárias passos em Personalizar propriedades de dispositivos.Versecountdown_timer_example := class(creative_device): @editable AddMoreTimeButton : button_device = button_device{}Adicione uma referência editável ao dispositivo Fim de Jogo em
countdown_timer_examplechamadaEndGame.Versecountdown_timer_example := class(creative_device): @editable AddMoreTimeButton : button_device = button_device{} @editable EndGame : end_game_device = end_game_device{}Salve seu arquivo Verse e, no menu principal do UEFN, escolha Verse, Compilar código Verse para atualizar seu dispositivo no nível a fim de ver suas alterações no painel Detalhes do dispositivo.
Iniciando a contagem regressiva
Neste exemplo, você criará uma classe Verse que desenha a própria interface de usuário e gerencia a própria contagem regressiva.
Siga estas etapas para criar o temporizador de contagem regressiva personalizado:
Crie um arquivo Verse vazio chamado countdown_timer.verse.
Adicione os seguintes módulos Verse na parte superior do arquivo:
Verseusing { /UnrealEngine.com/Temporary/UI } using { /UnrealEngine.com/Temporary/SpatialMath } using { /Fortnite.com/UI } using { /Verse.org/Colors } using { /Verse.org/Simulation }Crie uma classe chamada
countdown_timere adicione as seguintes variáveis:Uma variável float chamada
RemainingTimee inicializada como0.0.Versevar RemainingTime : float = 0.0Uma variável de widget de tela chamada
Canvas.Versevar Canvas : canvas = canvas{}Um widget de texto chamado
RemainingTimeWidgetcom uma cor de texto branca padrão.VerseRemainingTimeWidget : text_block = text_block{DefaultTextColor := NamedColors.White}Uma função que retorna uma mensagem chamada
RemainingTimeTextque leva um parâmetro de número inteiro para exibir o valor representado porRemainingTime.VerseRemainingTimeText<localizes>(CurrentRemainingTime : int) : message = "{CurrentRemainingTime}"Uma interface de usuário de jogador opcional chamada
MaybePlayerUIe inicializada comofalse.VerseMaybePlayerUI : ?player_ui = false
Sua classe deve ficar assim:
Versecountdown_timer := class: MaybePlayerUI : ?player_ui = false var RemainingTime : float = 0.0 var Canvas : canvas = canvas{} RemainingTimeWidget : text_block = text_block{DefaultTextColor := NamedColors.White} RemainingTimeText<localizes>(CurrentRemainingTime : int) : message = "{CurrentRemainingTime}"Adicione uma expressão
blockpara criar a interface de usuário em que o tempo aparece na parte superior central da tela. Uma expressão block em uma definição de classe é executada apenas quando a classe é instanciada, portanto, podemos criar a interface de usuário uma vez nessa expressãoblock.Versecountdown_timer := class: block: set Canvas = canvas: Slots := array: canvas_slot: Anchors := anchors: Minimum := vector2{X := 0.5, Y := 0.05} Maximum := vector2{X := 0.5, Y := 0.05} Alignment := vector2{X := 0.5, Y := 0.0} Offsets := margin{Top := 0.0, Left := 0.0, Bottom := 0.0, Right := 0.0}Adicione a função
StartCountdown()para exibir a interface de usuário.VerseStartCountdown() : void = Print("Starting countdown") if (PlayerUI := MaybePlayerUI?): PlayerUI.AddWidget(Canvas)Em countdown_timer_example.verse, crie uma instância
countdown_timercom uma referência à interface de usuário do jogador e ao tempo de início da contagem regressiva. ChameStartCountdown()emOnBegin()para que a contagem regressiva seja exibida assim que o jogo começar.Verseusing { /Verse.org/Simulation } using { /Fortnite.com/Devices } countdown_timer_example := class(creative_device): @editable AddMoreTimeButton : button_device = button_device{} @editable EndGame : end_game_device = end_game_device{}Se você testar agora, a interface de usuário não exibirá o tempo restante quando a contagem regressiva começar, então, em countdown_timer.verse, crie uma função chamada
UpdateUI()que atualiza o valor atual da contagem regressiva na interface de usuário. ChameUpdateUI()emStartCountdown().VerseStartCountdown() : void = Print("Starting countdown") if (PlayerUI := MaybePlayerUI?): PlayerUI.AddWidget(Canvas) # Update the UI when we start the timer to see the initial RemainingTime on screen UpdateUI() UpdateUI() : void =Agora, a contagem regressiva inicial aparece na interface de usuário, mas o valor não é atualizado a cada segundo. Para fazer isso:
Adicione a variável float
TimerTickPeriodpara representar a frequência em segundos de atualização da interface de usuário. Este exemplo usa um segundo.VerseTimerTickPeriod : float = 1.0 # The timer "precision": how often, in seconds, it ticks.Crie uma função chamada
RunCountdown(), que tenha o especificador suspends chamadaStartCountdown(). FaçaRunCountdown()aguardar oTimerTickPeriodantes de atualizar a interface de usuário e repita isso em loop. Defina o loop para terminar e faça com que a contagem regressiva desapareça da interface de usuário quando chegar a0.0.VerseStartCountdown() : void = Print("Starting countdown") if (PlayerUI := MaybePlayerUI?): PlayerUI.AddWidget(Canvas) # Update the UI when we start the timer to see the initial RemainingTime on screen UpdateUI() spawn:
Ao testar, você deve ver a contagem regressiva começar em 30 e ser atualizada a cada segundo até que o temporizador chegue a 0 e a contagem regressiva desapareça da interface de usuário.
Como adicionar mais tempo
Com esse temporizador de contagem regressiva, adicione uma forma personalizada de incluir mais tempo e indicar o tempo adicionado. Este exemplo mostra como adicionar mais tempo à contagem regressiva e exibimos o tempo adicionado quando o jogador interage com o dispositivo Botão.
Siga estas etapas para adicionar tempo ao temporizador de contagem regressiva quando o jogador interagir com o dispositivo Botão:
Em countdown_timer.verse, crie uma nova função chamada
AddRemainingTime()que atualiza a variávelRemainingTimecom o valor passado para a função no parâmetro float chamadoTimee, em seguida, atualize a interface de usuário para mostrar o novo tempo restante.VerseAddRemainingTime(Time : float) : void = set RemainingTime += Time # Immediately update the UI for better player feedback when time is added. UpdateUI()Em countdown_timer_example.verse, faça a inscrição em
InteractedWithEventdo dispositivo Botão e chameAddRainingTime()quando o jogador interagir com o dispositivo Botão.Verseusing { /Verse.org/Simulation } using { /Fortnite.com/Devices } countdown_timer_example := class(creative_device): @editable AddMoreTimeButton : button_device = button_device{} @editable EndGame : end_game_device = end_game_device{}Adicione um widget à classe
countdown_timerpara informar quanto tempo é adicionado à contagem regressiva quando o jogador interage com o botão.VerseAddedTimeWidget : text_block = text_block{DefaultTextColor := NamedColors.White} AddedTimeText<localizes>(AddedTime : int) : message = " +{AddedTime}!"Use os mesmos valores de posicionamento do widget `RemainingTime` para o novo `AddedTimeWidget`, mas altere os valores abaixo para que o tempo do texto explicativo seja exibido no canto superior direito do temporizador de contagem regressiva:
Para AddedTimeWidget, defina a margem esquerda em Offsets como
50.0.Para RemainingTimeWidget, defina a margem superior no deslocamento como
25.0.Versecountdown_timer := class: <# This block runs for each instance of the countdown_timer class. We can setup the canvas once here. #> block: set Canvas = canvas: Slots := array: canvas_slot: Anchors := anchors: Minimum := vector2{X := 0.5, Y := 0.05} Maximum := vector2{X := 0.5, Y := 0.05}
Crie uma nova função chamada
AddedTimeCallout()que atualiza o valor em AddedTimeWidget e exibe o texto explicativo por dois segundos antes de ocultar o widget novamente. ChameAddedTimeCallout()emAddRemainingTime().VerseAddRemainingTime(Time : float) : void = set RemainingTime += Time # Immediately update the UI for better player feedback when time is added. UpdateUI() # Fire a simple callout to show the time being added. spawn: AddedTimeCallout(Time)Ao testar, você deve ver a contagem regressiva começar em 30 e ser atualizada a cada segundo até que o temporizador chegue a 0 e a contagem regressiva desapareça da interface de usuário. Quando o jogador interage com o botão, vinte segundos são adicionados à contagem regressiva, e uma mensagem explicativa é exibida por dois segundos mostrando o tempo adicional acrescentado.
Sinalizando o fim do temporizador de contagem regressiva
Anteriormente neste tutorial, você usou o InteractedWithEvent de um dispositivo Botão para saber quando o jogador pressionou o botão e adicionou mais tempo ao temporizador de contagem regressiva. Porém, você também pode criar os próprios eventos personalizados que outras pessoas podem usar para saber quando algo acontece no código.
Este exemplo mostra como usar o comportamento de eventos personalizados abaixo:
Signal(): essa função permite que qualquer pessoa que esteja aguardando o evento saiba que o evento aconteceu.Await(): essa função assíncrona bloqueia a execução do contexto delimitador até que o evento seja sinalizado.
Neste exemplo, você adicionará um evento ao temporizador de contagem regressiva para sinalizar quando a contagem regressiva termina para que possa ativar o dispositivo Fim de Jogo.
Siga estas etapas para adicionar um evento ao final da contagem regressiva.
Adicione um campo de evento chamado
CountDownEndedEventà classe:VerseCountdownEndedEvent : event() = event(){}O
event()é um tipo paramétrico, ou seja, retorna uma classe ou interface em vez de um valor ou instância de objeto. É por isso que o tipo éevent()e por que você precisa inicializar sua constanteCountDownEndedEventcomevent(){}para imitar como uma classe é instanciada.Atualize
RunCountdown()para sinalizarCountdownEndedEventde forma que outro código saiba que a contagem regressiva terminou antes de sair do loop.VerseRunCountdown()<suspends> : void = # We loop with the TimerTickPeriod. # The UI is also updated each time. loop: Sleep(TimerTickPeriod) set RemainingTime -= TimerTickPeriod UpdateUI() # Timer End if (RemainingTime <= 0.0):Em countdown_timer_example.verse, aguarde
CountdownEndedEventassociado aCountdownTimere ative o dispositivo Fim de Jogo, porque sabemos que a contagem regressiva terminou quando o evento aconteceu.VerseOnBegin<override()<suspends> : void = AddMoreTimeButton.InteractedWithEvent.Subscribe(OnButtonInteractedWith) if: FirstPlayer := Self.GetPlayspace().GetPlayers()[0] PlayerUI := GetPlayerUI[player[FirstPlayer]] then: set CountdownTimer = countdown_timer{MaybePlayerUI := option{PlayerUI}, RemainingTime := InitialCountdownTime} CountdownTimer.StartCountdown() CountdownTimer.CountdownEndedEvent.Await()Ao testar, você deve ver a contagem regressiva começar em 30 e ser atualizada a cada segundo até que o temporizador chegue a 0. Assim que a contagem regressiva terminar, ela desaparecerá da interface de usuário e o jogo terminará. Quando o jogador interage com o botão, vinte segundos são adicionados à contagem regressiva, e uma mensagem explicativa é exibida por dois segundos mostrando o tempo acrescentado.
Como preparar uma classe para ser usada por outro código
Você já criou a própria classe personalizada de temporizador de contagem regressiva e usou um dispositivo criado com Verse para instanciar e controlar esse temporizador.
Quando você cria as próprias classes personalizadas (e qualquer outro código), é importante especificar quem pode acessar a criação. Por exemplo, somente o temporizador de contagem regressiva deve ser capaz de criar e alterar a própria interface de usuário. Em Verse, você pode usar os especificadores de acesso para definir o nível de acesso do seu código.
Adicione o especificador public a qualquer identificador que queira que outras pessoas acessem, pois public significa que o identificador é universalmente acessível. Neste exemplo, todos os itens a seguir são usados no dispositivo countdown_timer_example e, portanto, devem ter acesso público:
CountdownEndedEvent<public> : event() = event(){}StartCountdown<public>() : void =AddRemainingTime<public>(Time : float) : void =
Adicione o especificador private a qualquer identificador que não queira que outras pessoas acessem, pois private significa que o identificador só pode ser acessado no escopo atual, imediatamente delimitante (que neste caso é a classe countdown_timer).
Neste exemplo, estas linhas devem ter acesso privado:
RemainingTimeWidget<private> : text_block = text_block{DefaultTextColor := NamedColors.White}AddedTimeWidget<private> : text_block = text_block{DefaultTextColor := NamedColors.White}AddedTimeText<localizes><private>(AddedTime : int) : message = " +{AddedTime}!"RemainingTimeText<localizes><private>(CurrentRemainingTime : int) : message = "{CurrentRemainingTime}"var Canvas<private> : canvas = canvas{}TimerTickPeriod<private> : float = 1.0RunCountdown<private>()<suspends> : void =AddedTimeCallout<private>(Time : float)<suspends> : void =UpdateUI<private>() : void =
É uma boa ideia agrupar o código por acesso. Recomendamos ordenar o código da maior até a menor quantidade de acessos:
público
Interno
protegidos
privado
Você pode usar um constructor para definir valores iniciais para uma nova instância de classe sem expor as variáveis de uma classe. Um construtor é uma função especial que cria uma instância da classe à qual ele está associado.
Crie um constructor para a classe countdown_timer que atualize as variáveis RemainingTime e MaybePlayerUI.
MakeCountdownTimer<constructor><public>(MaxTime : float, InPlayer : agent) := countdown_timer:
RemainingTime := MaxTime
MaybePlayerUI := option{GetPlayerUI[player[InPlayer]]}
As variáveis RemainingTime e MaybePlayerUI definidas no constructor não devem ter acesso público, mas não poderão ter acesso privado se estiverem definidas em um constructor. Você pode usar o especificador internal para essas variáveis, o que significa que o identificador só pode ser acessado no módulo atual e imediatamente delimitante.
MaybePlayerUI<internal> : ?player_ui = falsevar RemainingTime<internal> : float = 0.0
Código completo
O código a seguir é o código completo para criar um temporizador de contagem regressiva personalizado.
Dois arquivos Verse foram criados neste exemplo.
countdown_timer.verse
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/UI }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Verse.org/Simulation }
using { /Fortnite.com/UI }
MakeCountdownTimer<constructor><public>(MaxTime : float, InPlayer : agent) := countdown_timer:
RemainingTime := MaxTime
MaybePlayerUI := option{GetPlayerUI[player[InPlayer]]}
countdown_timer_example.verse
using { /Verse.org/Simulation }
using { /Fortnite.com/Devices }
using { /UnrealEngine.com/Temporary/UI }
countdown_timer_example := class(creative_device):
@editable
AddMoreTimeButton : button_device = button_device{}
@editable
Por si só
Ao concluir este guia, você aprendeu a criar um temporizador de contagem regressiva personalizado.
Usando o que aprendeu, tente fazer o seguinte:
Altere a taxa de contagem do temporizador e adicione um evento para cada marcação.
Adicione as funcionalidades de pausa, retomada e reinicialização ao temporizador.