terça-feira, 15 de outubro de 2024

UEFN Verse: Constants and Variables

Constants and variables represent memory locations used to store values.

A constant receives its value at initialization and this value cannot be modified during program execution.

A variable can have its value modified at any time.

The creation of constants and variables are similar. The only difference is in the use of the var keyword to indicate that it is a variable. This is the creation format:

    var Identifier : type = initialization


Let's analyze each element from the line above:

  • var : Used to indicate the creation of a variable. If omitted, it means that a constant is being created.
  • Identifier : Name of the constant or variable.
  • type : Indicates the type of values ​​that can be stored.
  • initialization : Expression used to generate an initial value for the constant or variable.


There are several types that can be used in constants and variables. The most common types are described below:

  • logicIt can only store the Boolean values true or false.
  • int : Stores integer values.
  • float It can store numerical values that are not integers.
  • string : Used to store text (sequence of characters).
  • Reference : Used to reference instances of a class. For example, a creative device that is in the level.

The type of a constant can be omitted when creation is done inside a function (such as the OnBegin function). The format is as follows:

    Identifier := initialization


Let's create a simple device in UEFN to see examples of using constants and variables.

In any UEFN project, open Verse Explorer, right-click on the project name and choose the Add new Verse file to project option.

Select the Verse Device template. In Device Name, put const_var_device and click the Create button to use the template code.

Modify the Verse code of the const_var_device device to have this content:

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }

const_var_device := class(creative_device):

    # logic: Boolean values ​​(true or false) 
    @editable
    StartTimer : logic = false

    # string: Stores text. "" is an empty string
    @editable 
    Name : string = ""

    # float: Accepts numeric values ​​that are not integers
    @editable 
    HeightInMeters : float = 1.80

    # var: Indicates that it is a variable.
    # int: Stores integer values.
    var NameLength : int = 0

    # This constant is a reference to an instance of the timer_device class
    @editable 
    TimerDevice : timer_device = timer_device{}

    # This function runs when the device starts in-game
    OnBegin<override>()<suspends>:void=

        # The string type of the WelcomeMsg constant was inferred from the expression.
        # {Name} will be replaced by the value of the Name constant.
        WelcomeMsg := "Welcome {Name} to UEFN"

        # Use set to modify the value of a variable
        set NameLength = Name.Length

        # Print: It writes text on the screen and in the log 
        Print(WelcomeMsg)
        Print("{Name} has {NameLength} characters")
        
        # if: It executes a block of code if the result of the expression is true
        if(StartTimer?):
            TimerDevice.Start()

Lines starting with the # character are comments that are ignored by the Verse code.

@editable is a Verse language attribute that indicates that the constant or variable can be modified directly in UEFN.

Save the file and compile the Verse code using the Verse > Build Verse Code option from the UEFN menu.

To add our Verse device to the level, access the Content Drawer and the folder that has the project name plus Content.

Drag the const_var_device and drop it onto the level. Also drag onto the level a Timer Device which can be found in the Fortnite > Devices folder.

Select the const_var_device in the level. In the Details tab you can modify the values ​​of the constants that were marked with @editable. Check the checkbox for the StartTimer constant. Enter your name in the Name constant. Click on the TimerDevice drop-down to select the Timer Device that we added to the level.


Click the Launch Session button located in the UEFN toolbar to load the level into Fortnite. 

After starting the session in Fortnite, press the Tab key and select the Log tab to view the log with the messages written by the Print functions. Also verify that the Timer Device is started by our Verse code if the StartTimer constant value is true.


Table of Contents Verse


UEFN Verse: Constantes e Variáveis

Constantes e variáveis representam locais de memória usados para armazenar valores.

Uma constante recebe seu valor na inicialização e este valor não pode ser modificado durante a execução do programa.

Uma variável pode ter seu valor modificado a qualquer momento.

A criação de constantes e variáveis é parecida. A única diferença está no uso da palavra chave var para indicar que é uma variável. Este é o formato da criação:

    var Identificador : tipo = inicialização


Vamos analisar cada elemento da linha acima:

  • var : Usado para indicar a criação de uma variável. Se for omitido, significa que uma constante está sendo criada.
  • Identificador : Nome da constante ou variável.
  • tipo : Indica o tipo de valores que poderá ser armazenado.
  • inicialização : Expressão usada para gerar um valor inicial para a constante ou variável.


Existem diversos tipos que podem ser usados nas constantes e variáveis. Os tipos mais comuns estão descritos abaixo:

  • logic : Só pode armazenar os valores Booleano true ou false.
  • int : Armazena valores inteiros.
  • float : Pode armazenar valores numéricos que não são inteiros.
  • string : Usado para armazenar texto (sequência de caracteres).
  • Reference : Usada para referenciar instâncias de uma classe. Por exemplo, um dispositivo criativo que está no nível.

O tipo de uma constante pode ser omitido quando a criação é feita dentro de uma função (como a função OnBegin). O formato fica assim:

    Identificador := inicialização


Vamos criar um dispositivo simples no UEFN para vermos exemplos de uso das constantes e variáveis.

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.

Selecione o template Verse Device. Em Device Name coloque const_var_deviceclique no botão Create para usar o código do template.

Modifique o código Verse do dispositivo const_var_device para ficar com este conteúdo:

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }

const_var_device := class(creative_device):

    # logic: Valores Booleano (true ou false) 
    @editable
    StartTimer : logic = false

    # string: Armazena texto. "" é uma string vazia
    @editable 
    Name : string = ""

    # float: Aceita valores numéricos que não são inteiros
    @editable 
    HeightInMeters : float = 1.80

    # var: Indica que é uma variável.
    # int: Armazena valores inteiros. 
    var NameLength : int = 0

    # Esta constante é uma referência para uma instância da classe timer_device
    @editable 
    TimerDevice : timer_device = timer_device{}

    # Esta função executa quando o dispositivo é iniciado no jogo
    OnBegin<override>()<suspends>:void=

        # O tipo string da constante WelcomeMsg foi inferido a partir da expressão.
        # {Name} será substituído pelo valor da constante Name.
        WelcomeMsg := "Welcome {Name} to UEFN"

        # Use set para modificar o valor de uma variável
        set NameLength = Name.Length

        # Print: Escreve um texto na tela e no log 
        Print(WelcomeMsg)
        Print("{Name} has {NameLength} characters")
        
        # if: Executa um bloco de código se o resultado da expressão for true
        if(StartTimer?):
            TimerDevice.Start()

As linhas que começam com o caractere # são comentários ignorados pelo código Verse.

O @editable é um atributo da linguagem Verse que indica que a constante ou variável pode ser modificada diretamente no UEFN.

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

Para adicionar o nosso dispositivo Verse ao nível, acesse o Content Drawer e a pasta que tem o nome do projeto mais Content.

Arraste o const_var_device e solte-o no nível. Arraste também para o nível um Timer Device que pode ser encontrado na pasta Fortnite > Devices.

Selecione o const_var_device no nível. Na aba Details você pode modificar os valores das constantes que foram marcadas com @editable. Marque o checkbox da constante StartTimer. Coloque o seu nome na constante Name. Clique no drop-down de TimerDevice para selecionar o Timer Device que adicionamos ao nível.


Clique no botão Launch Session localizado na barra de ferramentas do UEFN para carregar o nível no Fortnite. 

Após iniciar a partida no Fortnite, pressione a tecla Tab e selecione a aba Log para visualizar o log com as mensagens escritas pelas funções Print. Verifique também que o Timer Device é iniciado pelo nosso código Verse se o valor da constante StartTimer for true.


Sumário Verse


sábado, 12 de outubro de 2024

Translations of my Blueprints/UE5 book

The purpose of this post is to share with you the joy I feel when I see my book Blueprints Visual Scripting for Unreal Engine 5 being translated and published in other languages.

This is the result of many years of work with Unreal Engine that started with my tutorials on programming in UnrealScript:

https://romerounrealscript.blogspot.com/p/table-of-contents.html

It was something I started without any pretensions but which generated opportunities that I decided to dedicate myself to.

My book was published in 2022:


The Korean version was published in 2023:


The Chinese version was published in 2024:



Translation into Russian is underway.


Currently, the focus of my studies is on the new Verse programming language. It is part of UEFN (Unreal Editor for Fortnite) but later it will be available in the standard Unreal Engine editor.

This is the link to my Verse language tutorials:

https://romeroblueprints.blogspot.com/p/table-of-contents-verse.html 


Traduções do meu livro de Blueprints/UE5

O objetivo desta postagem é compartilhar com vocês a alegria que eu sinto ao ver o meu livro em inglês Blueprints Visual Scripting for Unreal Engine 5 ser traduzido e publicado em outras línguas.

Isto é resultado de um trabalho de muitos anos com a Unreal Engine que iniciou com os meus tutoriais sobre programação em UnrealScript:

https://romerogames.blogspot.com/p/sumario-unrealscript.html

Foi algo que comecei sem pretensão mas que gerou oportunidades que decidi me dedicar.

O meu livro foi publicado em 2022:


A versão Coreana foi publicada em 2023:


A versão Chinesa foi publicada em 2024:



A tradução para Russo está em andamento.


Atualmente, o foco dos meus estudos está na nova linguagem de programação Verse. Ela faz parte do UEFN (Editor do Unreal para Fortnite) mas posteriormente estará disponível também no editor padrão da Unreal Engine.

Este é o link dos meus tutoriais da linguagem Verse: 

https://romeroblueprints.blogspot.com/p/sumario-verse.html


sábado, 28 de outubro de 2023

UEFN Verse: Final version of round_based_device

This is the last article in Part II. Let's add the Verse code that controls the Guard Spawner devices.

The Guard Spawner device references will be stored in an array. Add the array declaration after the RoundDevice variables. 

    @editable
    GuardSpawners : []guard_spawner_device = array{}


Enabling Guard Spawner devices according to the current round is done in a similar way to Capture Area devices. Add the EnableGuardSpawners function below that receives as a parameter the number of Guard Spawners that must be enabled.

    EnableGuardSpawners(NumberOfSpawners:int):void=        

        MaxIndex := NumberOfSpawners - 1

        for (Index := 0..MaxIndex):
            if(GuardSpawner := GuardSpawners[Index]):
                GuardSpawner.Enable()                


The EnableGuardSpawners function will be called during round setup. It receives the CurrentRound variable as a parameter. The code below shows how the Round1Setup function will look like. Do the same for the other round setup functions.

    Round1Setup():void=
        set CurrentRound = 1
        
        EnableCaptureAreas(CurrentRound)
        EnableGuardSpawners(CurrentRound)


With these changes we complete the Verse code for round_based_device. I decided to make a simple game to keep the focus on the round setup functions that are associated with the Round Settings devices. Within these functions you have countless possibilities for creating different rounds.

The Verse code for the final version of round_based_device looks like this:

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }

round_based_device := class(creative_device):

    @editable
    EndGameDevice : end_game_device = end_game_device{}

    @editable 
    CaptureAreas: []capture_area_device = array{}

    var NumberOfAreasCaptured : int = 0

    var CurrentRound : int = 0

    @editable
    Round1Device : round_settings_device = round_settings_device{}

    @editable
    Round2Device : round_settings_device = round_settings_device{}

    @editable
    Round3Device : round_settings_device = round_settings_device{}

    @editable
    Round4Device : round_settings_device = round_settings_device{}

    @editable
    Round5Device : round_settings_device = round_settings_device{}

    @editable
    GuardSpawners : []guard_spawner_device = array{}

    OnBegin<override>()<suspends>:void=
        Round1Device.RoundBeginEvent.Subscribe(Round1Setup)
        Round2Device.RoundBeginEvent.Subscribe(Round2Setup)
        Round3Device.RoundBeginEvent.Subscribe(Round3Setup)
        Round4Device.RoundBeginEvent.Subscribe(Round4Setup)
        Round5Device.RoundBeginEvent.Subscribe(Round5Setup)

    AreaCaptured(Agent:agent):void=
        set NumberOfAreasCaptured += 1

        if( NumberOfAreasCaptured = CurrentRound):
            EndGameDevice.Activate(Agent)

    EnableCaptureAreas(NumberOfAreas:int):void=        
        MaxIndex := NumberOfAreas - 1

        for (Index := 0..MaxIndex):
            if(Area := CaptureAreas[Index]):
                Area.Enable()
                Area.AreaIsScoredEvent.Subscribe(AreaCaptured)

    EnableGuardSpawners(NumberOfSpawners:int):void=        

        MaxIndex := NumberOfSpawners - 1

        for (Index := 0..MaxIndex):
            if(GuardSpawner := GuardSpawners[Index]):
                GuardSpawner.Enable()                
            
    Round1Setup():void=
        set CurrentRound = 1
        
        EnableCaptureAreas(CurrentRound)
        EnableGuardSpawners(CurrentRound)
                            
    Round2Setup():void=
        set CurrentRound = 2
        
        EnableCaptureAreas(CurrentRound)
        EnableGuardSpawners(CurrentRound)

    Round3Setup():void=
        set CurrentRound = 3
        
        EnableCaptureAreas(CurrentRound)
        EnableGuardSpawners(CurrentRound)
     
    Round4Setup():void=
        set CurrentRound = 4
        
        EnableCaptureAreas(CurrentRound)
        EnableGuardSpawners(CurrentRound)

    Round5Setup():void=
        set CurrentRound = 5
        
        EnableCaptureAreas(CurrentRound)
        EnableGuardSpawners(CurrentRound)
    


Save the file and compile the Verse code using the Verse > Build Verse Code option from the UEFN menu.

Select the round_based_device in the level. In the Details tab, add 5 elements to the GuardSpawners array and select the Guard Spawners device references:


Save the level and start the session. Each round, another Guard Spawner will be enabled, which will spawn 2 guards.



It will be difficult to complete the last rounds. I'll give you some tips:
  • Use the Verse device that is in the level to hide and protect yourself from gunfire.
  • When capturing an area, stay crouched and moving to avoid the guards' shots.
  • Try to eliminate one of the guards and run to get the rifle he drops.


I hope this example helps you in learning and practicing the Verse language. We still have a long way to go.


Table of Contents Verse


UEFN Verse: Versão final do round_based_device

Este é o último artigo da Parte II. Vamos adicionar o código Verse que controla os dispositivos Guard Spawner.

As referências dos dispositivos Guard Spawner serão armazenadas em um array. Adicione a declaração do array depois das variáveis RoundDevice. 

    @editable
    GuardSpawners : []guard_spawner_device = array{}


A habilitação dos dispositivos Guard Spawner conforme o round atual é feita de uma forma semelhante ao dos dispositivos Capture Area. Adicione a função EnableGuardSpawners abaixo que recebe como parâmetro o número de Guard Spawners que devem ser habilitados.

    EnableGuardSpawners(NumberOfSpawners:int):void=        

        MaxIndex := NumberOfSpawners - 1

        for (Index := 0..MaxIndex):
            if(GuardSpawner := GuardSpawners[Index]):
                GuardSpawner.Enable()                


A função EnableGuardSpawners será chamada durante o setup dos rounds. Ela recebe a variável CurrentRound como parâmetro. O código abaixo mostra como vai ficar a função Round1Setup. Faça o mesmo para as outras funções de setup dos rounds.

    Round1Setup():void=
        set CurrentRound = 1
        
        EnableCaptureAreas(CurrentRound)
        EnableGuardSpawners(CurrentRound)


Com estes ajustes completamos o código Verse do round_based_device. Eu decidi fazer um jogo simples para manter o foco nas funções de setup dos rounds que estão associadas aos dispositivos Round Settings. Dentro dessas funções você tem inúmeras possibilidades para a criação de rounds diferenciados.

O código Verse da versão final do round_based_device fica assim:

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }

round_based_device := class(creative_device):

    @editable
    EndGameDevice : end_game_device = end_game_device{}

    @editable 
    CaptureAreas: []capture_area_device = array{}

    var NumberOfAreasCaptured : int = 0

    var CurrentRound : int = 0

    @editable
    Round1Device : round_settings_device = round_settings_device{}

    @editable
    Round2Device : round_settings_device = round_settings_device{}

    @editable
    Round3Device : round_settings_device = round_settings_device{}

    @editable
    Round4Device : round_settings_device = round_settings_device{}

    @editable
    Round5Device : round_settings_device = round_settings_device{}

    @editable
    GuardSpawners : []guard_spawner_device = array{}

    OnBegin<override>()<suspends>:void=
        Round1Device.RoundBeginEvent.Subscribe(Round1Setup)
        Round2Device.RoundBeginEvent.Subscribe(Round2Setup)
        Round3Device.RoundBeginEvent.Subscribe(Round3Setup)
        Round4Device.RoundBeginEvent.Subscribe(Round4Setup)
        Round5Device.RoundBeginEvent.Subscribe(Round5Setup)

    AreaCaptured(Agent:agent):void=
        set NumberOfAreasCaptured += 1

        if( NumberOfAreasCaptured = CurrentRound):
            EndGameDevice.Activate(Agent)

    EnableCaptureAreas(NumberOfAreas:int):void=        
        MaxIndex := NumberOfAreas - 1

        for (Index := 0..MaxIndex):
            if(Area := CaptureAreas[Index]):
                Area.Enable()
                Area.AreaIsScoredEvent.Subscribe(AreaCaptured)

    EnableGuardSpawners(NumberOfSpawners:int):void=        

        MaxIndex := NumberOfSpawners - 1

        for (Index := 0..MaxIndex):
            if(GuardSpawner := GuardSpawners[Index]):
                GuardSpawner.Enable()                
            
    Round1Setup():void=
        set CurrentRound = 1
        
        EnableCaptureAreas(CurrentRound)
        EnableGuardSpawners(CurrentRound)
                            
    Round2Setup():void=
        set CurrentRound = 2
        
        EnableCaptureAreas(CurrentRound)
        EnableGuardSpawners(CurrentRound)

    Round3Setup():void=
        set CurrentRound = 3
        
        EnableCaptureAreas(CurrentRound)
        EnableGuardSpawners(CurrentRound)
     
    Round4Setup():void=
        set CurrentRound = 4
        
        EnableCaptureAreas(CurrentRound)
        EnableGuardSpawners(CurrentRound)

    Round5Setup():void=
        set CurrentRound = 5
        
        EnableCaptureAreas(CurrentRound)
        EnableGuardSpawners(CurrentRound)
    


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

Selecione o round_based_device no nível. Na aba Detailsadicione 5 elementos no array GuardSpawnersselecione as referências dos dispositivos Guard Spawners:


Salve o nível e inicie a sessão. A cada round será habilitado mais um Guard Spawner que irá gerar 2 guardas.



Vai ficar difícil concluir os últimos rounds. Vou dar algumas dicas:

  • Use o dispositivo Verse que está no nível para se esconder e se proteger dos tiros.
  • Quando estiver capturando uma área, fique agachado e se movendo para evitar os tiros dos guardas.
  • Tente eliminar um dos guardas e corra para pegar o rifle que ele deixa cair.


Espero que este exemplo ajude vocês no aprendizado e prática da linguagem Verse. Ainda temos um longo caminho pela frente. 


Sumário Verse


UEFN Verse: Guard Spawner device

The Guard Spawner device can spawn a group of enemies to attack players. We can define the type of guard, the quantity and the frequency.

Our game will have 5 Guard Spawner devices. Each device will spawn two guards. The number of enabled Guard Spawner devices corresponds to the current round.

Let's add a Guard Spawner device and make the changes. Then we will make 4 copies of this Guard Spawner.

Go to the Content Drawer and the Fortnite > Devices folder. Search by guard. Drag the Guard Spawner device and drop it onto the level in the grid line above the line that has Capture Areas 4 and 5.


The image below shows the guard types available on the Guard Spawner device:


In the Details tab, choose one of the guard types and uncheck the Enabled at Game Start property: 



In our game, each Guard Spawner device will only spawn 2 guards. The guards will be part of the Team Index 2 so they will consider the player as an opponent  because the player is on the Team Index 1.

Uncheck the Allow Infinite Spawn property. Set the value 2 to Total Spawn Limit. In Guard Team Index put Team Index 2. Uncheck the Show Spawn Radius property to improve the level's visualization during editing. 


We will reduce the visibility of the guards to allow the player to capture some areas without the guards noticing.

In Visibility Range put the value 20. Change Visibility Range Restriction to Always.


Make 4 copies of the Guard Spawner device and place them on the same grid line as shown at the top of this image:


Modify the Guard Type on each of the Guard Spawners to have a variety of enemies in the game.

In the next article we will see how Guard Spawners devices will be enabled by Verse code according to the current round. If you want to test, you can manually enable some Guard Spawners by checking the Enabled at Game Start property.


Table of Contents Verse