sexta-feira, 5 de dezembro de 2025

UEFN Verse SG: Criando um componente Scene Graph

Neste artigo vamos criar um simples componente Scene Graph que irá nos ajudar a entender a relação entre entidade, componente e Prefab.

O nosso componente irá gerar uma espécie de ponte de plataformas. Ele terá dois campos que serão usados para definir o número de plataformas geradas e a distância entre elas.

A imagem abaixo mostra a ponte de plataformas que será gerada:


Vamos usar o modo de modelagem do UEFN para criar uma mesh que será a plataforma. Mude o editor para modo Modeling:


No painel de modelagem, seleciona a forma Cylinder:


Mude a altura (Height) do Cylinder para 50 e selecione algum material. Eu escolhi o material MI_Japanese_Wooden_Floor.


Clique no nível para posicionar o mesh e depois clique no botão Accept para criar o mesh.



No Content Drawer, veja que foi criada a pasta Meshes dentro da pasta do seu projeto. Acesse a pasta, selecione o mesh e pressione F2 pra renomear. Renomeie o Static Mesh para Platform_cylinder. De dois cliques no mesh para abrir o static mesh editor.

Precisamos adicionar colisão na mesh. Vamos usar uma forma simples. No menu Collision, escolha a opção Add Box Simplified Collision. Salve e feche o editor.


É necessário compilar o código verse para que seja criada o mesh component em Verse que representa o mesh que criamos.  Para compilar acesse o menu Verse > Compile Verse Code.


Agora vamos criar o Prefab que representará uma plataforma. Acesse o Content Drawer, selecione a pasta do seu projeto e clique com o botão direito e um espaço vazio para abrir o menu. Selecione Entity Prefab Definition e coloque o nome Prefab_platform para este Prefab.



Dê dois cliques no
Prefab_platform que foi criado para abrir o editor de Prefab. Na aba Details, clique no botão +Component e selecione o transform_component. Este componente é necessário para definir a posição, rotação e escala da entidade no nível.


Adicione outro componente e selecione o mesh_component. Serão exibidos os mesh_components disponíveis no projeto. Selecione o Platform_cylinder que criamos.


A imagem abaixo do editor do Prefab mostra como ficou o Prefab_platform.



Salve o Prefab e feche o editor Prefab.

Quando criamos um Prefab, o UEFN cria uma classe Verse deste Prefab e registra no arquivo Assets.digest.verse. Isto permite a criação de instâncias do Prefab direto no código Verse.

O próximo passo é a criação do componente Scene Graph que irá gerar várias instâncias do Prefab_platform em posições diferentes e adicioná-las à entidade que possui o componente. 

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

Escolha o template Scene Graph Component e coloque o nome platform_row_component. Clique no botão Create Empty.


Dê um duplo clique no arquivo platform_row_component para abri-lo no Visual Studio Code.

Copie o código Verse abaixo para o componente platform_row_component:

using { /Verse.org }
using { /Verse.org/Native }
using { /Verse.org/SceneGraph }
using { /Verse.org/Simulation }
using { /Verse.org/SpatialMath }

platform_row_component<public> := class<final_super>(component):

    @editable
    NumberOfPlatforms<public>:int = 10

    @editable
    PlatformDistance<public>:float = 300.0

    OnBeginSimulation<override>():void =
        # Run OnBeginSimulation from the parent class
        (super:)OnBeginSimulation()

        for (Index := 0..NumberOfPlatforms - 1):
            Position := vector3{Forward := PlatformDistance * Index}

            NewPlatform := Prefab_platform{}

            NewPlatform.SetLocalTransform( transform{Translation := Position} )
            
            Entity.AddEntities( array{NewPlatform} )        
             
    OnSimulate<override>()<suspends>:void =
        Print("OnSimulate")


Vamos analisar este código por partes. A linha abaixo está declarando que platform_row_component é uma classe que herda da classe component. Ou seja, component é a classe pai e também é conhecida como a superclasse.

platform_row_component<public> := class<final_super>(component): 

O especificador <public> indica que a classe estará disponível em toda parte. O especificador <final_super> é uma exigência do Scene Graph para garantir a integridade do sistema de entidades e componentes.

O nosso componente possui dois campos que podem ser editados direto no UEFN para configurar a geração da ponte de plataformas.
    @editable
    NumberOfPlatforms<public>:int = 10

    @editable
    PlatformDistance<public>:float = 300.0

Estes campos usam o especificador <public> para que fiquem visíveis para outros componentes. Na programação com Scene Graph, a interação entre componentes  é muito comum, por isso o uso de constantes com acesso <public> facilita o acesso a estes dados sem correr o risco deles serem modificados por outros componentes.

O código de template do Scene Graph componente traz duas funções onde você pode colocar o código que será executado ao iniciar a simulação:
  •  OnBeginSimulation<override>( ) : Esta função tem execução e conclusão imediata. Ideal para códigos de preparação do componente que serão executados somente um vez. 
  •  OnSimulate<override>()<suspends> : O especificador <suspends> indica que esta é uma função assíncrona, ou seja sua conclusão não precisa ser imediata. Por exemplo, aqui você pode colocar um código que faz o componente aguardar uma interação do jogador.

O código de geração da ponte de plataforma está na função OnBeginSimulation<override>. Logo no início desta função, temos a seguinte linha de código:
    (super:)OnBeginSimulation()

A classe component que é usada como superclasse dos componentes, possui a função OnBeginSimulation() que deve ter algum código de configuração que deve ser executado. O (super:) indica que a função OnBeginSimulation() que será executada é a da superclasse.

A expressão for é usada para repetir o seu bloco de código para cada plataforma que será gerada. O valor de Index é modificado para cada iteração do for. O primeiro valor é 0 e o último valor será NumberOfPlatforms - 1.
    for (Index := 0..NumberOfPlatforms - 1): 

Dentro do laço for é usado o valor de Index para calcular a posição onde a nova instância do Prefab_platform será criada.

Position := vector3{Forward := PlatformDistance * Index} 

Esta posição é relativa à posição da entidade que terá o nosso componente. As plataformas serão criadas seguindo o eixo Forward. Para mudar a direção que a ponte de plataformas será criada, basta rotacionar a entidade no nível.

Nota: Desde a versão 36.00, a UEFN passou a usar o sistema de coordenada LUF. Neste sistema os eixos de coordenadas são Left, Up e Forward. Para saber mais sobre o LUF, acesse esta documentação da Epic Games:

Left-Up-Forward Coordinate System


A constante NewPlatform armazena uma nova instância do nosso Prefab_platform:

NewPlatform := Prefab_platform{} 


A função SetLocalTransform() especifica a transformação relativa da plataforma. Em nosso exemplo, só precisa definir o campo Translation do transform. A rotação e escala usam os valores padrões.

NewPlatform.SetLocalTransform( transform{Translation := Position} ) 


A nova instância do Prefab_platform precisa ser adicionada à entidade que contém o nosso componente. A classe component possui a constante Entity que é uma referência à esta entidade. A função AddEntities adiciona um array de entidades à uma entidade. Por isso foi preciso criar um array contendo a instância referenciada por NewPlatform.

Entity.AddEntities( array{NewPlatform} )


Estas ações são repetidas para cada iteração do laço for.

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

Para concluir este exemplo é preciso adicionar uma entidade ao nível e adicionar o nosso componente platform_row_component à esta entidade. Siga estes passos:

1. No UEFN, acesse o painel Place Actors. Se o painel não estiver visível, acesse ele pelo menu superior Window.

2. Em Place Actors, selecione a categoria Entities e arraste o entity para o nível. Na aba Outliner, renomeie esta nova entidade para PlatformBridge para facilitar a identificação.

3.  Na aba Details, clique no botão +Component e selecione o nosso componente platform_row_component.


4. Na aba Details, você pode modificar os valores que são usados na geração da ponte de plataformas.


5. Posicione a entidade um pouco acima do piso do nível para evitar que a ponte de plataformas seja criada no piso.


Salve o nível e carregue no Fortnite clicando no botão Launch Session para ver a ponte de plataformas gerada pelo nosso componente. 


Nota: Infelizmente, não está funcionando corretamente a colisão das plataformas que foram geradas pelo código Verse. A minha ideia com este exemplo era para o jogador pular nas plataformas para conseguir passar por algum abismo. Só que o jogador não consegue ficar em cima da plataforma. 

O Prefab criado está correto. Se adicionarmos uma instância do Prefab direto no nível pelo UEFN, a colisão funciona corretamente e o jogador consegue ficar em cima da plataforma.

Pesquisei na internet sobre essa situação e confirmei que o código Verse está correto. Encontrei em uma página da Epic Games sobre problemas do Scene Graph o seguinte item:



Este é o problema que deve estar ocorrendo com nosso exemplo. O Scene Graph ainda está em Beta e logo eles devem corrigir este problema.
(Dezembro de 2025)