Ao concluir esta etapa do tutorial Quebra-cabeça de luzes marcadas, você aprenderá a usar Tags de jogabilidade para encontrar atores marcados com uma tag específica enquanto o jogo está em execução. Tags de jogabilidade permitem trabalhar com vários dispositivos sem precisar configurar suas referências no editor. Isso pode abrir oportunidades de jogabilidade interessantes em que, por exemplo, seu código muda dinamicamente quais dispositivos estão ativos conforme o jogador avança no jogo.
Siga estas etapas para criar uma nova Tag de jogabilidade e atribuí-la a todas as luzes no nível do enigma:
- Abra o Explorador do Verse e clique duas vezes em tagged_lights_puzzle.verse para abrir o script no Visual Studio Code.
- No topo do arquivo de código:
- Adicione
using { /Verse.org/Simulation/Tags }para fazer referência à classetage use a funçãoGetCreativeObjectsWithTag(). -
Adicione
using { /Verse.org/Simulation }para tornar as propriedades editáveis.~~~(verse) using { /Fortnite.com/Devices } using { /Verse.org/Native } using { /UnrealEngine.com/Temporary/Diagnostics } using { /Verse.org/Simulation/Tags } using { /Verse.org/Simulation }
log_tagged_lights_puzzle := class(log_channel){} ~~~
- Adicione
-
Acima da classe
log_tagged_lights_puzzle, adicione uma nova subclasse chamadapuzzle_lightque herda da classetag. O nome da classe herdada torna-se uma Tag de jogabilidade personalizada para você usar em qualquer dispositivo do Modo Criativo.~~~(verse) # Derive da classe
tagno módulo Verse.org/Simulation/Tags para criar uma nova tag de jogabilidade. puzzle_light := class(tag){}log_tagged_lights_puzzle := class(log_channel){} ~~~
- Na barra de ferramentas do UEFN, clique em Compilar scripts do Verse para compilar seu código e sua nova tag de jogabilidade
puzzle_lightpara seu projeto. - No Outliner do UEFN, selecione um Dispositivo de Luz Personalizável para abrir seu painel Detalhes.
- No painel Detalhes:
- Clique em Adicionar novo componente e escolha VerseTagMarkup.
- Selecione o componente VerseTagMarkup para visualizar suas configurações no painel Detalhes.
- Em Tags de jogabilidade, edite a propriedade Tags e adicione a tag
puzzle_light.

Várias tags podem ser adicionadas ao mesmo dispositivo e, portanto, cada dispositivo pode pertencer a vários grupos ao mesmo tempo. Por exemplo, um dispositivo com
tag1etag2será encontrado ao chamarGetCreativeObjectsWithTag(tag1{})ouGetCreativeObjectsWithTag(tag2{}). - Na definição de classe
tagged_lights_puzzle, adicione dois campos de matriz variável:- Uma matriz variável
logiceditável chamadaLightsStatepara representar o estado atual de todas as luzes (se elas estão apagadas ou acesas). Ela também é usada para definir o estado inicial das luzes e, portanto, seu número de elementos deve corresponder ao número de luzes marcadas com a tagpuzzle_light. Neste exemplo, todas as luzes estão apagadas por padrão, então o valor inicial para todas as luzes éfalse. ~~~(verse) @editable var LightsState : []logic = array{false, false, false, false} ~~~ - Uma matriz variável editável
customizable_light_devicechamadaLightspara armazenar todos os dispositivos de Luz Personalizável marcados com a tag de jogabilidadepuzzle_light. ~~~(verse) @editable var Lights : []customizable_light_device = array{} ~~~
- Uma matriz variável
-
Quando o jogo começa, o dispositivo deve definir as luzes para corresponder à configuração inicial especificada na matriz
LightsStatee salvar as referências na matrizLights, para que elas possam ser atualizadas quando o estado do jogo mudar. Esse trabalho será feito em um método chamadoSetupPuzzleLights() : voide chamado no métodoOnBegin(), para que as luzes sejam acesas quando o jogo começar. ~~~(verse) SetupPuzzleLights() : void = Logger.Print("Configurando as luzes do jogo")OnBegin
() : void = SetupPuzzleLights() ~~~ - Em
SetupPuzzleLights(), encontre todos os dispositivos com a tagpuzzle_lightchamandoGetCreativeObjectsWithTag(puzzle_light{})e salve-os em uma matriz chamadaTaggedActors. ComoTaggedActorsé uma matriz constante cujo escopo é local para o métodoSetupPuzzleLights(), você não precisa especificar explicitamente um tipo para essa matriz, porque o tipo pode ser inferido nesse contexto. ~~~(verse) SetupPuzzleLights() : void = Logger.Print("Configurando as luzes do jogo") TaggedActors := GetCreativeObjectsWithTag(puzzle_light{}) ~~~Diferentes chamadas da função
GetCreativeObjectsWithTag()podem colocar os dispositivos em diferentes ordens no resultado da matriz, porque não há ordem garantida ao recuperar atores com tags de jogabilidade. - Agora que você coletou todos os dispositivos que possuem a tag
puzzle_light, certifique-se de que cada luz corresponda ao estado inicial especificado pela matrizLightsState. Você pode usar um loopforpara percorrer todos os dispositivos marcados. ~~~(verse) for: ActorIndex -> TaggedActor : TaggedActors do: TaggedActor ~~~ - A função
GetCreativeObjectsWithTag()retorna uma matriz do tipocreative_object_interface. Neste exemplo, você vai querer interagir com cadaTaggedActorcomo umcustomizable_light_devicepara poder acender ou apagar a luz.- Você pode converter uma classe em uma de suas subclasses (processo chamado de conversão de tipo) usando a sintaxe
NewDeviceReference := device_type_to_cast_to[DeviceReference], em quedevice_type_to_cast_toé o tipo de dispositivo desejado, neste exemplo,customizable_light_device. Esta é uma expressão falível porque a conversão de tipo falhará se o dispositivo não puder ser convertido naquele tipo (por exemplo, se for um tipo de dispositivo diferente). ~~~(verse) LightDevice := customizable_light_device[TaggedActor] ~~~
A função
GetCreativeObjectsWithTag()tem o tipo de retorno[]creative_object_interfaceporque a função pode retornar diferentes tipos de atores, então seu tipo de retorno é a interface que todos os atores devem implementar para serem retornados porGetCreativeObjectsWithTag(). Consulte Tags de jogabilidade para saber mais.- Com expressões
for, você pode usar expressões falíveis como um filtro e criar novas variáveis que podem ser usadas no bloco de códigofor. Nesse caso, adicione a conversão de tipo acustomizable_light_deviceda etapa anterior para a expressão de iteração. ~~~(verse) for: ActorIndex -> TaggedActor : TaggedActors LightDevice := customizable_light_device[TaggedActor] do: LightDevice ~~~ - A última expressão em um bloco de código é o resultado desse bloco de código. A expressão
forretorna o resultado do bloco de código de cada iteração em uma matriz, portanto, o resultado dessa expressãoforé uma matriz de referênciascustomize_light_deviceque foram marcadas compuzzle_light. Isso significa que você pode atualizar a matrizLightscom o resultado da expressãofordiretamente. ~~~(verse) set Lights = for: ActorIndex -> TaggedActor : TaggedActors LightDevice := customizable_light_device[TaggedActor] do: LightDevice ~~~ - Esse loop
fortambém deve chamarTurnOn()/TurnOff()nas luzes para corresponder à configuração inicialLightsStateno editor. A expressãoforpode retornar o índice usado para obter o dispositivo marcado atual (ActorIndexno exemplo), que você pode usar para indexar na matrizLightsStatepara ver se a luz deve estar acesa ou apagada. ~~~(verse) set Lights = for: ActorIndex -> TaggedActor : TaggedActors LightDevice := customizable_light_device[TaggedActor] ShouldLightBeOn:= LightsState[ActorIndex] do: LightDevice ~~~ - Em seguida, chame
TurnOn()/TurnOff()dependendo deShouldLightBeOnfortrue/false. Você pode usar uma expressãoifpara executar diferentes expressões com base em uma condição (especificamente uma expressão falível). Neste caso, a expressão falível pode usar o operador de consulta?comIsLightOn, que terá sucesso seShouldLightBeOnfortrue(portanto, chameTurnOn()) e falhará seShouldLightBeOnforfalse(então chameTurnOff()). ~~~(verse) set Lights = for: ActorIndex -> TaggedActor : TaggedActors LightDevice := customizable_light_device[TaggedActor] ShouldLightBeOn := LightsState[ActorIndex] do: if (ShouldLightBeOn?) then LightDevice.TurnOn() else LightDevice.TurnOff() LightDevice ~~~ - É uma boa ideia também imprimir o índice da luz e seu valor inicial para que você possa verificar se seu código está funcionando conforme o esperado e comparar com o que você vê no nível.
- Ao usar
{}no meio de uma string, a expressão entre{}é avaliada primeiro, e seu valor é adicionado à string. Portanto, você pode usar uma expressãoifno meio de uma string para adicionar valores condicionalmente. ~~~(verse) set Lights = for: ActorIndex -> TaggedActor : TaggedActors LightDevice := customizable_light_device[ActorIndex] ShouldLightBeOn := LightsState[ActorIndex] do: Logger.Print("Adicionando luz no índice {ActorIndex} com State:{if (ShouldLightBeOn?) then "On" else "Off"}") if (ShouldLightBeOn?) then LightDevice.TurnOn() else LightDevice.TurnOff() LightDevice ~~~~
- Você pode converter uma classe em uma de suas subclasses (processo chamado de conversão de tipo) usando a sintaxe
- Seu método
SetupPuzzleLights()agora deve ficar assim: ~~~(verse) SetupPuzzleLights() : void = TaggedActors := GetCreativeObjectsWithTag(puzzle_light{}) <# Para cada dispositivo com a tag puzzle_light, verifique se é um customize_light_device tentando convertê-lo nesse tipo. Se for, obtenha seu LightState inicial para TurnOn() ou TurnOff() LightDevice. Salve todos os customize_light_device marcados na matriz Lights. #> set Lights = for: ActorIndex -> TaggedActor : TaggedActors LightDevice := customizable_light_device[TaggedActor] ShouldLightBeOn := LightsState[ActorIndex] do: Logger.Print("Adicionando luz no índice {ActorIndex} com State:{if (ShouldLightBeOn?) then "On" else "Off"}") if (ShouldLightBeOn?) then LightDevice.TurnOn() else LightDevice.TurnOff() LightDevice ~~~ - Salve o script no Visual Studio Code.
- Na barra de ferramentas do UEFN, clique em Compilar scripts do Verse para compilar seu código.
- Clique em Play na barra de ferramentas do UEFN para testar o nível.
Ao fazer o teste de jogo do seu nível, você deve ver cada luz adicionada à matriz Lights, junto com seu estado inicial, impresso no registro de saída.
Próxima etapa
Na próxima etapa deste tutorial, você aprenderá a acender e apagar um conjunto específico de luzes quando o jogador pressiona os botões.