Esta seção mostrará como determinar e personalizar equipes e classes para os jogadores.
Dispositivos utilizados:
Configurações de Equipe e Inventário
Use os dispositivos Configurações de Equipe e Inventário para definir os nomes e as cores das equipes para exibição na tabela de pontuação.
Inclua um dispositivo para cada equipe em uma área que não seja visível para os jogadores. Para configurar a equipe de adereços, configure as Opções do Usuário de forma que correspondam à tabela a seguir.
| Opção | Valor | Explicação |
|---|---|---|
| Nome da Equipe | Adereços | Determina uma sequência de texto para identificar a equipe na tabela de pontuação e nos elementos do HUD. |
| Cor da Equipe | Azul-céu | Determina uma cor para a equipe selecionada para ser usada na tabela de pontuação, no HUD e em alguns dispositivos. |
| Equipe | Índice da equipe: 1 | Especifica a qual equipe as configurações neste dispositivo são aplicadas. |
Para configurar a equipe de caçadores, configure as Opções do Usuário do outro dispositivo de forma que correspondam à tabela a seguir.
| Opção | Valor | Explicação |
|---|---|---|
| Nome da Equipe | Caçadores | Determina uma sequência de texto para identificar a equipe na tabela de pontuação e nos elementos do HUD. |
| Cor da Equipe | Laranja | Determina uma cor para a equipe selecionada para ser usada na tabela de pontuação, no HUD e em alguns dispositivos. |
| Equipe | Índice da equipe: 2 | Especifica a qual equipe as configurações neste dispositivo são aplicadas. |
Criador de Classes
Use um Criador de Classes para modificar as equipes que acabou de criar.
Coloque dois dispositivos Criador de Classes, um para cada equipe, em uma área que não seja visível para os jogadores. Para personalizar a equipe de adereços, configure as Opções do Usuário de forma que correspondam à tabela a seguir.
| Opção | Valor | Explicação |
|---|---|---|
| Nome da Classe | Adereço | Define o nome desta classe. |
| Descrição da Classe | Esconda-se dos caçadores. Sobreviva. | Define a descrição dessa classe. |
| Identificador de classe | Slot de classe: 1 | Define o identificador único para essa classe. |
| Vida Máx. | 1 | Determina a vida máxima dos jogadores durante o jogo. Os adereços serão eliminados com um acerto. |
| Lista de Itens | Adereçador | Define a lista de itens que esta classe terá. |
| Equipar Item Concedido | Primeiro Item | Determina qual item na lista será equipado. |
Para personalizar a equipe de caçadores, configure as Opções do Usuário do outro dispositivo de forma que correspondam à tabela a seguir.
| Opção | Valor | Explicação |
|---|---|---|
| Nome da Classe | Caçador | Define o nome desta classe. |
| Descrição da Classe | Encontre os adereços. Elimine-os. | Define a descrição dessa classe. |
| Identificador de classe | Slot de classe: 2 | Define o identificador único para essa classe. |
| Lista de Itens | Pistola com Lanterna | Define a lista de itens que esta classe terá. |
| Equipar Item Concedido | Primeiro Item | Determina qual item na lista será equipado. |
Seletor de Classe
Combine o Criador de Classes com o Seletor de Classe para gerenciar as classes e equipes personalizadas que você cria.
Juntamente com Verse, as configurações deste dispositivo fazem com que os jogadores no Espaço de Classe 1 sejam transferidos para o Espaço de Classe 2 quando ressurgirem.
Coloque dois dispositivos Seletor de Classe, um para cada equipe, em uma área que não seja visível para os jogadores. Para gerenciar a equipe de adereços, use as configurações da tabela abaixo e configure as Opções do Usuário para este dispositivo.
| Opção | Valor | Explicação |
|---|---|---|
| Classe para a qual alternar | Espaço de classe: 1 | Determina a classe para a qual o jogador deve alternar. |
| Visível Durante o Jogo | False | Este dispositivo não ficará visível durante o jogo. |
| Áudio da Área | False | Determina se o Seletor de Classe reproduz efeitos sonoros quando os jogadores entram na área. |
| Classe para a qual alternar | Índice da equipe: 1 | Determina a equipe para a qual o jogador será alternado. |
| Limpar Itens ao Alternar | True | Determina se os itens são removidos do inventário do jogador ao alternar. |
| Volume Visível no Jogo | False | Determina se o volume do dispositivo ficará visível durante o jogo. |
| Exibir Efeitos Visuais ao Ativar | False | Determina se o dispositivo deve criar um efeito visual quando o jogador muda de classe ou equipe. |
Para gerenciar a equipe de caçadores, use as configurações da tabela abaixo e configure as Opções do Usuário para este dispositivo.
| Opção | Valor | Explicação |
|---|---|---|
| Classe para a qual alternar | Espaço de classe: 2 | Determina a classe para a qual o jogador deve alternar. |
| Classe para a qual alternar | Índice da equipe: 2 | Determina a equipe para a qual o jogador será alternado. |
Como criar funcionalidade de equipe com Verse
Há duas equipes neste jogo de Caça aos Adereços. Deve ser possível executar algumas ações semelhantes nas duas equipes para fazer com que o jogo funcione. Por exemplo:
-
Adicionar jogadores a uma equipe.
-
Remover jogadores de uma equipe.
-
Exibir informações sobre suas equipes aos jogadores.
Para criar essa funcionalidade para as duas equipes sem duplicar o código, você criará uma classe com o especificador <abstract>. Classes com o especificador abstract destinam-se a ter funcionalidade parcial que suas subclasses herdam e a partir das quais expandem. Você criará primeiro uma classe abstrata chamada base_team e dará a ela a funcionalidade que as duas equipes compartilharão.
Esse documento inclui trechos de Verse que mostram como executar as mecânicas de jogo necessárias nesse modo de jogo. Siga as etapas a seguir e copie o script completo na etapa 6 deste tutorial.
Crie um novo arquivo Verse no seu projeto chamado base_team.verse. Esse não será um dispositivo Verse, então, você pode criá-lo como um arquivo Verse vazio.
~~~(verse) using { /Fortnite.com/Characters } using { /Fortnite.com/Devices } using { /Fortnite.com/UI } using { /UnrealEngine.com/Temporary/Diagnostics } using { /UnrealEngine.com/Temporary/SpatialMath } using { /UnrealEngine.com/Temporary/UI } using { /Verse.org/Colors } using { /Verse.org/Simulation } log_team := class(log_channel){}
Esta classe define os dispositivos necessários para as diferentes equipes da experiência.
Esta classe é abstrata, portanto não pode ser usada sozinha. Deve ser herdada por outra classe.
base_team := class
Agora que você tem essa classe, pode criar as classes para a equipe de adereços e de caçadores. Como cada uma delas herdará de `base_team`, temos algumas vantagens:
* O código a ser implementado para cada equipe é muito mais curto porque já têm suas funções e dados comuns definidos em `base_team`.
* É mais fácil entender qual código é específico de cada equipe, porque estão em suas próprias classes e não misturados em um código comum.
* É muito mais fácil adicionar mais equipes ao modo de jogo. Todas as equipes novas herdam de `base_team` e o código que diferencia a nova equipe fica em sua própria classe.
Lembre-se que você não pode criar uma instância de uma classe com o especificador `<abstract>`. Você deve criar uma classe que herda da classe abstrata e instanciar essa classe.
### Equipe de caçadores
Primeiro, crie a classe para a equipe de caçadores. Crie um novo arquivo Verse no seu projeto chamado **hunter_team.verse**. Esse não será um dispositivo Verse, então, você pode criá-lo como um arquivo Verse vazio.
Declare uma classe chamada `hunter_team`. Ela deve ser `<concrete>` e também herdar de `base_team`.
~~~(verse)
hunter_team := class<concrete>(base_team):
~~~
Criar uma classe `<concrete>` significa que todos os campos da classe devem ter um valor padrão. Consulte [Especificadores e atributos](https://dev.epicgames.com/documentation/en-us/uefn/specifiers-and-attributes-in-verse) para saber mais.
A seguir é apresentado o código completo para o script "hunter_team.verse".
A classe `hunter_team` tem duas funções com o mesmo nome que as funções na classe `base_team`. Isso é permitido porque ambas têm o especificador `<override>`. Isso significa que quando essas funções são chamadas em uma instância de `hunter_team`, a versão na classe `hunter_team` é usada.
Por exemplo, no código a seguir, a versão de `InitializeAgent()` definida em `hunter_team` será usada porque substitui a função de mesmo nome em `base_team`. Compare essa situação com a chamada a `Count()` que usará a versão definida em `base_team` porque não existe função de substituição.
~~~(verse)
HunterTeam:hunter_team = hunter_team{}
# Usa a função de "hunter_team".
HunterTeam.InitializeAgent(StartingHunterAgent)
# Usa a função de "base_team".
HunterTeam.Count()
As duas funções substituídas também usam (super:). O que permite que chamem a versão das funções definidas em base_team porque base_team é a superclasse de hunter_team. No caso de InitializeAgent() e EliminateAgent(), as duas usam Logger.Print() para gerar algo no log. Depois, elas chamam suas respectivas funções de base_team. O que significa que as funções funcionam exatamente da mesma forma que as versões em base_team, exceto pelas chamadas de Logger.Print().
Consulte Subclasse para saber mais sobre <override> e (super:).
Equipe de adereços
Agora crie a classe para a equipe de adereços. Crie um novo arquivo Verse no seu projeto chamado prop_team.verse. Esse não será um dispositivo Verse, então, você pode criá-lo como um arquivo Verse vazio.
É preciso gerenciar mais elementos para os membros da equipe de adereços. Eles têm efeitos de batimentos cardíacos que precisam ser iniciados e interrompidos em um cronômetro e a distância que eles se movimentam. Também precisam ser transferidos para a equipe de caçadores quando são eliminados.
Para gerenciar os membros da equipe de adereços, você usará o método RunPropGameLoop(). Esse método pode ser pensando como o gerenciador para toda a jornada de um adereço pelo jogo. Desde o momento em que surge até o momento que é eliminado ou sai do jogo, esse método será executado para todos os membros da equipe de adereços.
~~~(verse)
# Se o agente de adereço parar de se mover, então execute uma corrida ("race") para ver se ele se move além do valor de "MinimumMoveDistance", o cronômetro de batimento cardíaco termina ou o agente adereço é eliminado.
RunPropGameLoop(PropAgent:agent)
`RunPropGameLoop()` tem um parâmetro, `PropAgent`. Ele é uma constante que representa um jogador na equipe de adereços. Ele também tem o especificador `<suspends>`, o que significa que leva tempo para terminar. Nesse caso, ele não concluirá até que o `PropAgent` passado não esteja mais na equipe de adereços.
Toda a funcionalidade deste método está contida em uma expressão de corrida (race). Assim, o método não será concluído até que uma das expressões dentro dessa corrida seja concluída. Essas expressões são:
* `PropAgent.AwaitNoLongerAProp()`
* `loop`
A expressão `loop` dentro dessa corrida nunca terminará. Sua finalidade é ser infinita. O que significa que `AwaitNoLongerAProp()` é o método que **sempre** vence a corrida e conclui o método. Usar a corrida dessa forma é o mesmo que dizer ao seu programa para executar um determinado conjunto de códigos repetidamente até que algo aconteça. Consulte [Race (corrida)](https://dev.epicgames.com/documentation/pt-br/uefn/race-in-verse) para saber mais sobre essa poderosa expressão.
Com esse código, `AwaitNoLongerAProp()` vence a corrida.
~~~(verse)
# Executar o loop até que o agente de adereço não faça mais parte da matriz PropAgents. A remoção acontece se o agente de adereço for eliminado e transformado em caçador ou se o jogador sair da sessão.
(PropAgent:agent).AwaitNoLongerAProp()<suspends>:void =
loop:
if (not FindOnTeam[PropAgent]):
Logger.Print("Cancelando comportamento do agente adereço.")
break
Sleep(0.0) # Avança para a próxima marcação do jogo.
Este método verifica constantemente se PropAgent está na equipe de adereços. Ele inicia com um loop que é executado até que not FindOnTeam[PropAgent] seja efetivado e depois interrompido, completando o método. Consulte Loop e break para saber mais sobre eles.
FindOnTeam[] é uma função falível declarada em base_team. Ela é efetivada se PropAgent for encontrado na equipe de adereços. Mas você precisa usar o operador not porque deseja interromper o loop somente quando PropAgent não for encontrado na equipe de adereços. Consulte Operadores para saber mais sobre not.
Por fim, você precisa adicionar Sleep(0.0) no final do loop. Essa expressão garante que o loop seja executado e depois avance para a próxima atualização de simulação. Como você não precisa executar essa verificação com mais frequência, Sleep(0.0) é adicionado para ajudar no desempenho. Consulte Sleep na página Referência à API do Verse para saber mais.
Agora que você sabe como AwaitNoLongerAProp() funciona, pode escrever o loop infinito que faz uma corrida com ele em RunPropGameLoop().