domingo, 25 de abril de 2021

Criando uma Blueprint Function Library em C++

Durante o desenvolvimento de um projeto você precisará criar algumas funções que são necessárias em diversas partes do projeto, tanto em C++ quanto em Blueprints. Para estes casos, você pode criar uma Blueprint Function Library em C++ para reunir essas funções em um único lugar.

Vamos criar uma Blueprint Function Library simples em nosso projeto para mostrar o funcionamento na prática.

No Content Browser, acesse a pasta TutoPart3 que está dentro da pasta C++ Classes. Clique com o botão direito em um espaço livre e escolha a opção New C++ Class...


Na tela seguinte, escolha a classe Blueprint Function Libray como classe pai e clique no botão Next.


No campo Name coloque TutoBPFunctionLibrary. No campo Path, mantenha a pasta padrão do projeto. Clique no botão Create Class

O nosso exemplo conterá apenas uma função, mas você pode criar várias funções em uma Blueprint Function Library, desde que todas elas sejam static

O nome da função de exemplo é GetNumberOfInstances. Ela retorna o número de instâncias que existem no nível atual da classe passada como parâmetro.

Adicione a declaração da função no arquivo TutoBPFunctionLibrary.h como mostra o código abaixo. 

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "TutoBPFunctionLibrary.generated.h"


UCLASS()
class TUTOPART3_API UTutoBPFunctionLibrary : public UBlueprintFunctionLibrary
{
  GENERATED_BODY()

  UFUNCTION(BlueprintCallable, Category = TutoBPLibrary, 
            meta = (WorldContext = "WorldContextObject") )
  static int32 GetNumberOfInstances(UObject* WorldContextObject, 
                                    TSubclassOf < AActor > ActorClass );	
};

O primeiro parâmetro da função é o WorldContextObject que é uma referência para o nível atual. Foi usado o especificador WorldContext para preenchê-lo automaticamente no node Blueprint, como foi explicado no artigo anterior.

No segundo parâmetro foi usado um TSubclassOf para que sejam aceitas somente subclasses de Actor.

Adicione a implementação da função GetNumberOfInstances() no arquivo TutoBPFunctionLibrary.cpp

#include "TutoBPFunctionLibrary.h"
#include "Kismet/GameplayStatics.h"

int32 UTutoBPFunctionLibrary::GetNumberOfInstances(UObject* WorldContextObject, 
                                                   TSubclassOf < AActor > ActorClass)
{
 TArray< AActor* > InstancesFound;

 UGameplayStatics::GetAllActorsOfClass(WorldContextObject,ActorClass, InstancesFound);
 
 return InstancesFound.Num(); 
}

Foi usada a função GetAllActorsOfClass() da classe UGameplayStatics. Esta função preenche um TArray com as referências das instâncias existentes no nível atual da classe passada como parâmetro. A nossa função GetNumberOfInstances() retorna a quantidade de elementos do TArray.

Compile o código C++.

Vamos usar a função GetNumberOfInstances() em Blueprint para verificar se todos os canhões inimigos foram destruídos. Quando isto ocorrer, será exibida uma mensagem na tela.

Abra o Blueprint FirstPersonGameMode que está na Pasta FirstPersonBP/Blueprints. Clique com o botão direito no Event Graph, role a listagem até encontrar a categoria Tuto BPLibrary e selecione a função Get Number Of Instances


A imagem abaixo é o node Blueprint que representa a nossa função. No parâmetro Actor Class, selecione a classe EnemyCannon.


No Event BeginPlay vamos criar um Timer que vai executar um evento customizado chamado CheckCannons uma vez por segundo. O evento CheckCannons chama a função Get Number Of Instance. Se o número de instâncias de EnemyCannon for igual a zero, então o node Print String exibe uma mensagem na tela. O script Blueprint deve ficar assim: 


Para adicionar o evento customizado, clique com o botão direito no Event Graph e escolha a opção Add Custom Event.

Compile o Blueprint e inicie o jogo. Destrua todos os canhões do nível para ver se a mensagem é exibida.


Sumário C++