UE4 Inventário para Multiplayer # 2 | Conectar o Blueprint ao C ++




Modo de jogo Em um artigo anterior, falei sobre como criar um DataAsset e por que é tão agradável e conveniente. Aqui veremos como acessar o DataAsset , mais precisamente os dados atribuídos a ele, do Blueprint e C ++ .


Ao longo do caminho, responderemos à questão de acessar qualquer Blueprint do C ++ .




Com a interação do Blueprints , tudo fica bem transparente.
Devido ao fato de termos fechado o acesso direto ao nosso banco de dados, não podemos apenas acessá-lo no Blueprint . Preste atenção ao protegido: no código abaixo.


protected: /* This is the main Database for all Items. It contains constant common variables */ UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "ItemsDatabase") TMap<FGameplayTag, FItemsDatabase> ItemsDataBase; 

I.e. nosso repositório estará visível apenas em classes herdadas, e isso é bom, porque criamos funções para chamar dados com segurança.


 /* Used in the widget */ UFUNCTION(BlueprintCallable, Category = "ItemDatabase") FORCEINLINE UTexture2D * GetItemIconTexture(const FGameplayTag & ItemNameTag) const; 

BlueprintCallable significa apenas que esta função pode ser usada no Blueprint . Se você leu o artigo anterior , provavelmente percebeu que outras funções de chamar esse atributo não possuem. Isso foi feito apenas porque os dados que eles chamaram não eram necessários no momento no Blueprint . Se alguém não precisa saber de algo, não temos pressa em denunciá-lo.


O próximo passo é criar uma variável em qualquer tipo de Blueprint do banco de dados que criamos (no meu caso, é BP_DreampaxItemsDataAsset ).


Depois disso, extraímos facilmente a textura atribuída com facilidade.




Agora considere como acessar informações em C ++ .
Não podemos simplesmente nos referir à classe DreampaxItemsDataAsset , porque ela não contém nenhuma informação. Precisamos ter acesso ao BP_DreampaxItemsDataAsset .


Existem dois métodos principais para acessar o Blueprint .
Primeiro, considere um método de conexão inconveniente usando a muleta ConstructorHelpers. Nesse caso, acesso à textura.


 ASHUD::ASHUD(const class FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { /* You can use the FObjectFinder in C++ to reference content directly in code. Although it's advisable to avoid this and instead assign content through Blueprint child classes. */ static ConstructorHelpers::FObjectFinder<UTexture2D> HUDCenterDotObj(TEXT("/Game/UI/HUD/T_CenterDot_M.T_CenterDot_M")); CenterDotIcon = UCanvas::MakeIcon(HUDCenterDotObj.Object); } 

O exemplo é retirado do maravilhoso projeto EpicSurvivalGameSeries , perfeito para aprender Multiplayer em C ++ . O autor estabeleceu uma meta para mostrar o maior número possível de métodos e técnicas de programação de um jogo em C ++ .


Por que esse método é inconveniente? O mesmo problema do DataTable - se você alterar o nome ou o local do Blueprint , o arquivo não será encontrado.


O mais preferível é o método no qual declaramos uma variável no arquivo de cabeçalho para sua atribuição subsequente já no Blueprint herdado. Para o exemplo acima, pode ser assim:


  UPROPERTY(EditDefaultsOnly, Category = "AimPointer") FCanvasIcon CenterDotIcon; 

Muito mais fácil, certo?
Atribuição de textura



Agora, sabendo como acessar qualquer Blueprint , podemos conectar facilmente nosso banco de dados.


 UCLASS() class ADreampaxGameMode : public AGameMode { GENERATED_BODY() public: ADreampaxGameMode(const FObjectInitializer & ObjectInitializer); ///////////////////////////////////////////////////////////////////////////// //Data Bases ///////////////////////////////////////////////////////////////////////////// public: /* Connect data base in BP for items*/ UPROPERTY(EditDefaultsOnly, Category = "Database") class UDreampaxItemsDataAsset * DreampaxItemsDataAsset; FORCEINLINE UDreampaxItemsDataAsset * GetDreampaxItemsDataAsset() const; 

Uma pequena digressão para não profissionais sobre como declarar variáveis

Como uma pessoa quase não familiarizada com C ++ , quebrei muitas cópias, tentando descobrir como declarar variáveis personalizadas corretamente.


Se o objetivo é declarar uma variável da classe que criamos, como


 UDreampaxItemsDataAsset * DreampaxItemsDataAsset; //  class UDreampaxItemsDataAsset * DreampaxItemsDataAsset; 

Pessoalmente, não entendi há algum tempo quando usar a aula e quando não.


Tudo acabou sendo dolorosamente simples.


  1. Se você não definir a classe , precisará incluir #include "Data / DreampaxItemsDataAsset.h" , contendo a declaração dessa classe.
  2. Se você definir a classe , #include "Data / DreampaxItemsDataAsset.h" já poderá ser feito em .cpp .
  3. E mais uma opção do parágrafo anterior, se você precisar declarar muitas variáveis ​​dessa classe ao mesmo tempo. Imediatamente depois de tudo #include, pré-declare nossa classe de classe UDreampaxItemsDataAsset; e declare as variáveis ​​sem o prefixo da classe .

Qual desses métodos está correto - não posso dizer. Se alguém explicar, ficarei agradecido.


Criamos uma variável na classe C ++ ADreampaxGameMode , uma vez que é visível apenas para o servidor, e tudo o que estiver conectado ao spawn do objeto deve passar apenas pelo servidor. Esta classe é o pai de BP_DreampaxGameMode , onde conectamos nosso BP_DreampaxItemsDataAsset .


Conexão BP_DreampaxItemsDataAsset
Conexão BP_DreampaxItemsDataAsset

Agora todo o poder do C ++ pode ser usado para trabalhar com os dados do nosso banco de dados.


No próximo artigo (finalmente!) Falaremos sobre a criação de inventário e descobriremos por que não podemos ficar sem o DataAsset já criado.


Se você tiver dúvidas ou sugestões para divulgar qualquer aspecto com mais detalhes, escreva nos comentários.

Source: https://habr.com/ru/post/pt418951/


All Articles