Neste artigo vamos programar um rotacionador de Props. Props são itens que podem ser adicionados a um nível do Fortnite. Os Props são muito utilizados na montagem do cenário e a maioria deles podem ser destruídos para fornecer materiais para o jogador.
É um exemplo simples mas que será útil para mostrar alguns recursos interessantes da linguagem Verse em ação.
Em qualquer projeto UEFN, abra o Verse Explorer, clique com o botão-direito no nome do projeto e escolha a opção Add new Verse file to project.
Em Device Name coloque props_rotator e clique no botão Create para usar o código do template.
No início do arquivo adicione o módulo SpatialMath e crie uma constante com o nome TimeRot180 do tipo float com valor default de 2.0, como mostra o código abaixo:
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/SpatialMath}
props_rotator := class(creative_device):
@editable
TimeRot180 : float = 2.0
O módulo SpatialMath é necessário porque usaremos uma função chamada ApplyYaw() que modifica a rotação ao redor do eixo Z.
A constante TimeRot180 armazena o tempo em segundos que um Prop levará para dar meia volta (180 graus).
Vamos criar uma função chamada RotateProp que receberá um creative_prop como parâmetro e irá manter este Prop rotacionando.
Esta função precisa ser assíncrona, por isso usaremos o especificador suspends.
O código da função RotateProp é este:
RotateProp(Prop : creative_prop)<suspends>:void=
loop:
PropTransform := Prop.GetTransform()
PropLocation := PropTransform.Translation
PropRotation := PropTransform.Rotation
NewRotation := PropRotation.ApplyYaw(180.0)
Prop.MoveTo(PropLocation, NewRotation, TimeRot180)
A função RotateProp obtém a estrutura transform do Prop para ter acesso à localização e rotação atual do Prop. É usada a função ApplyYaw para criar uma nova rotação que modifica a rotação atual do Prop em 180 graus ao redor do eixo Z.
Usaremos a função MoveTo da classe creative_prop para que o Prop modifique a sua rotação ao longo do tempo que está armazenado na constante TimeRot180. Quando o Prop completar a rotação, a expressão loop executará o bloco de código novamente fazendo com que o Prop rotacione continuamente.
Observe que a expressão loop que repete o bloco de código responsável pela rotação não tem nenhuma expressão break ou return para encerrar o loop, ou seja, é um loop infinito.
Um código assim em outras linguagens de programação que não possui contexto assíncrono provavelmente irá travar seu computador ao ser executado. Mas como veremos na linguagem Verse é muito simples criar um contexto assíncrono independente para executar esta função sem interromper o fluxo de execução do jogo.
Para completar o código do dispositivo props_rotator, defina um array de creative_prop e modifique a função OnBegin para ficar desta forma:
@editable
PropsToRotate : []creative_prop = array{}
OnBegin<override>()<suspends>:void=
for (PropInstance : PropsToRotate):
spawn{ RotateProp(PropInstance) }
Na função OnBegin temos a expressão for que irá repetir o bloco de código abaixo dela para cada elemento do array.
A expressão spawn inicia uma expressão assíncrona (a função RotateProp) e continua a execução do fluxo principal. Para cada um dos Props que forem adicionados ao array haverá um contexto assíncrono executando a função RotateProp.
A expressão spawn é um tipo de concorrência não estruturada. A recomendação na linguagem Verse é a de tentar usar as expressões de concorrência estruturadas como sync, race, rush e branch. O spawn deve ser usado como último recurso em alguns casos específicos.
O código Verse completo do dispositivo props_rotator fica assim:
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/SpatialMath}
props_rotator := class(creative_device):
@editable
TimeRot180 : float = 2.0
@editable
PropsToRotate : []creative_prop = array{}
OnBegin<override>()<suspends>:void=
for (PropInstance : PropsToRotate):
spawn{ RotateProp(PropInstance) }
RotateProp(Prop : creative_prop)<suspends>:void=
loop:
PropTransform := Prop.GetTransform()
PropLocation := PropTransform.Translation
PropRotation := PropTransform.Rotation
NewRotation := PropRotation.ApplyYaw(180.0)
Prop.MoveTo(PropLocation, NewRotation, TimeRot180)
Salve o arquivo e compile o código Verse usando a opção Verse > Build Verse Code do menu do UEFN.
Adicione o props_rotator e alguns Props no nível para serem rotacionados pelo nosso dispositivo. Uma boa opção para visualizar a rotação é o Prop com nome Farm_WeatherVane_01.
Selecione o props_rotator no nível e na aba Details adicione algumas referências de Props no array PropsToRotate. Você também pode alterar o tempo de rotação na propriedade TimeRot180.
Salve o nível e inicie a sessão. Observe a rotação dos Props que foram adicionados ao PropsToRotate.