segunda-feira, 19 de junho de 2023

Pegando objetos com tags em Verse

No artigo anterior nós criamos a tag coin_spawner para identificar os Item Spawners que estão no nível. Neste artigo vamos usar a função GetCreativeObjectsWithTag usando como parâmetro a tag coin_spawner para pegar as referências dos Item Spawners.

Na Unreal Engine, os objetos que podem ser adicionados ao nível são conhecidos como Atores.

Vamos criar uma função com o nome SetupCoinSpawnerDevices que preencherá o array CoinSpawnerDevices com as referências dos Item Spawners do nível.

O retorno da função GetCreativeObjectsWithTag será armazenado no array TaggedActors. Não será armazenado diretamente no array CoinSpawnerDevices porque precisamos garantir que o Ator que recebeu a tag coin_spawner é realmente um Item Spawner.

Este é o código da função SetupCoinSpawnerDevices:

    SetupCoinSpawnerDevices():void=

        TaggedActors := GetCreativeObjectsWithTag(coin_spawner{})

        set CoinSpawnerDevices = for:
            TaggedActor : TaggedActors
            ItemDevice := item_spawner_device[TaggedActor]
        do:
            ItemDevice

        SpawnCoin() 

O array CoinSpawnerDevices será preenchido com o resultado do laço for. Cada iteração do laço for adiciona um ItemDevice se o Cast de TaggedActor para item_spawner_device não falhar. A linha onde é feito o Cast é esta:

            ItemDevice := item_spawner_device[TaggedActor]

TaggedActor é o elemento do array TaggedActors que está sendo usado na iteração atual do laço for. O TaggedActor é uma referência do tipo actor que é uma superclasse de item_spawner_device. Usamos o Cast para converter a referência de actor para item_spawner_device. Se TaggedActor não for da classe item_spawner_device então o Cast irá falhar e o bloco do: não será executado na iteração atual, então o elemento atual não será adicionado no array CoinSpawnerDevices.

No final da função SetupCoinSpawnerDevices, após o preenchimento do array CoinSpawnerDevices, está sendo chamado a nossa função SpawnCoin para gerar a moeda em um dos Item Spawners do array.

Na função OnBegin, remova o SpawnCoin() e coloque a função  SetupCoinSpawnerDevices():

    OnBegin<override>()<suspends>:void=
        TimerDevice.SuccessEvent.Subscribe(HandleTimerFinished)
        SetupCoinSpawnerDevices()


Após as mudanças deste artigo, o código Verse do collect_game_device tem de ficar assim:

# v0.4
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /Verse.org/Random }
using { /Verse.org/Simulation/Tags }

coin_spawner := class(tag){}

collect_game_device := class(creative_device):

    @editable
    TimerDevice : timer_device = timer_device{}

    @editable
    EndGameDevice : end_game_device = end_game_device{}

    @editable
    var CoinSpawnerDevices : []item_spawner_device = array{}

    OnBegin<override>()<suspends>:void=
        TimerDevice.SuccessEvent.Subscribe(HandleTimerFinished)
        SetupCoinSpawnerDevices()
        
    HandleTimerFinished(MaybeAgent:?agent):void=
        if(Agent := MaybeAgent?):
            EndGameDevice.Activate(Agent)

    SpawnCoin():void=    
        if: 
            IndexSpawner: int = GetRandomInt(0, CoinSpawnerDevices.Length - 1)
            NextCoinSpawner := CoinSpawnerDevices[IndexSpawner]
        then:
            NextCoinSpawner.SpawnItem()

    SetupCoinSpawnerDevices():void=

        TaggedActors := GetCreativeObjectsWithTag(coin_spawner{})

        set CoinSpawnerDevices = for:
            TaggedActor : TaggedActors
            ItemDevice := item_spawner_device[TaggedActor]
        do:
            ItemDevice

        SpawnCoin()

Salve o arquivo e compile o código Verse usando a opção Verse > Build Verse Code do menu do UEFN.

Cada vez que o jogo for iniciado, a moeda será gerada aleatoriamente em um dos Item Spawners.


Sumário Verse