Neste artigo, tentarei revelar o significado e a metodologia da criação do DataAsset , como um repositório para vários tipos de dados e, no nosso caso, é uma biblioteca para atores e seus parâmetros.
Uma pequena introdução para pularPara tomar a decisão de criar um jogo há cerca de 2 anos, me ajudou a encontrar informações sobre o Unreal Engine 4 acidentalmente e a ler como é legal e simples. De fato, é muito difícil para uma pessoa que não sabe escrever código (uma linguagem de programação não importa nesse contexto) criar algo que é mais complicado do que uma pequena modificação de um conjunto padrão de peças do mecanismo. Portanto, o desejo inicial de fazer um super mega-jogo, com o crescimento do conhecimento sobre a realidade desse projeto, tornou-se gradualmente um hobby. Aumentar todas as camadas do desenvolvimento de jogos, desde modelagem e animação em 3D e escrever código, para uma pessoa parece um empreendimento pouco viável. No entanto, este é um bom treino para o cérebro.
Por que você decidiu escrever alguma coisa? Provavelmente por causa disso. que os manuais apresentados fornecem conhecimentos muito superficiais (e existem muitos), ou mesmo para um profissional, e contêm apenas instruções gerais.
É quase sempre melhor começar do começo. Não posso dizer que sempre faço isso, mas tentarei afirmar da maneira mais consistente possível.
Obviamente, é melhor começar com a estrutura, mas, infelizmente, com uma caixa fechada com ferramentas, é muito difícil entender o que exatamente pode ser construído com a ajuda deles. Então, vamos abrir esta caixa e ver o que está dentro.
A primeira pergunta a responder. Por que DataAsset ?
- Muitas vezes, em artigos e tutoriais, você pode ver o uso do DataTable . Por que isso é ruim? Se você armazenar um endereço para um Blueprint específico, ao renomear ou movê-lo para outra pasta, você será forçado a alterar esse endereço manualmente. Concordo - desconfortável? Com o DataAsset , isso não acontecerá. Todas as comunicações serão atualizadas automaticamente. Se você estiver absolutamente confiante na estrutura do seu projeto nos próximos anos, é claro que poderá usar as tabelas.
- A segunda vantagem inegável é a capacidade de armazenar tipos de dados complexos, como estruturas ( Struct ).
Agora um pouco sobre as desvantagens relativas. De fato, vejo apenas um. Essa é a necessidade de escrever código C ++ .
Se você já entende que, sem trabalhar com o código, não fará nada épico , isso não é uma desvantagem, mas um recurso.
Note-se que há uma solução alternativa - usar o Actor como um repositório. Mas esse aplicativo parece a última desculpa para não querer aprender C ++ e tem o potencial de acabar em um beco sem saída no futuro.
Se você está convencido de que tudo o que você precisa para o seu projeto pode ser feito no Blueprint , use as tabelas.
Agora que você já acredita que o DataAsset é bom, considere como criá-lo para o seu projeto.
Para aqueles que ainda estão completamente "fora do tanque"Há uma descrição muito detalhada das etapas e com fotos no fórum em russo dedicado ao UE4 . Basta pesquisar no Google "UE4 DataAsset" para . Ele dominou o básico deste manual cerca de um ano atrás.
Primeiro, crie uma classe C ++ , como Child do UDataAsset .
(Todo o código abaixo foi retirado do meu projeto por nascer. Apenas renomeie os nomes como desejar.)
Agora, com base nesta classe, você pode criar o Blueprint com segurança, mas é muito cedo para fazê-lo ... até agora, é apenas um manequim. No entanto, observe que as inclusões para texturas e nomes já foram feitas.
A partir deste momento, você começa a criar a estrutura do seu repositório. Ele será refeito muitas vezes, por isso recomendo não encher imediatamente seu armazenamento. Três a cinco elementos, no nosso caso, itens de inventário, são suficientes para testes. Às vezes, após a compilação, seu Blueprint pode ficar vazio, o que é extremamente desagradável se você já tiver preenchido uma dúzia ou duas posições.
Você pode criar uma estrutura diretamente no arquivo de cabeçalho, porque nesse caso, é improvável que seja aplicado em outro lugar. Normalmente, prefiro fazê-lo como um arquivo de cabeçalho separado “SrtuctName.h” e conectá-lo sempre que necessário, conforme necessário.
No meu caso, parece que isso USTRUCT(BlueprintType) struct FItemsDatabase { GENERATED_USTRUCT_BODY() UPROPERTY(EditDefaultsOnly, Category = "ItemsDatabase") TMap<FGameplayTag, float> ItemData; UPROPERTY(EditDefaultsOnly, Category = "ItemsDatabase") FGameplayTagContainer ItemPropertyTags; UPROPERTY(EditDefaultsOnly, Category = "ItemsDatabase") UTexture2D* IconTexture; UPROPERTY(EditDefaultsOnly, Category = "ItemsDatabase") TSubclassOf<class ADreampaxOutfitActor> ItemOutfitClass; UPROPERTY(EditDefaultsOnly, Category = "ItemsDatabase") TSubclassOf<class ADreampaxPickupActor> ItemPickupClass;
Seja contas com o TMap . Não replicado! Nesse caso, não importa.
Observe que eu não uso o FName . De acordo com as tendências modernas, o uso do FGameplayTag é considerado mais correto, porque reduz significativamente o risco de erro e possui várias vantagens que serão úteis mais tarde.
DataTable para GameplayTag exportado do Excel Também é uma boa prática definir funções para chamar variáveis na estrutura, como GetSomething () . Aparentemente, ainda preciso trabalhar na minha educação, já que está neste banco de dados, ainda não fiz essa ligação.
Veja como isso pode ser feito usando outro banco de dados como exemplo. USTRUCT(BlueprintType) struct FBlocksDatabase { GENERATED_USTRUCT_BODY() UPROPERTY(EditDefaultsOnly, Category = "BlocksDatabase") TSubclassOf<class ADreampaxBuildingBlock> BuildingBlockClass; UPROPERTY(EditDefaultsOnly, Category = "BlocksDatabase") FVector DefaultSize; UPROPERTY(EditDefaultsOnly, Category = "BlocksDatabase") FVector SizeLimits; UPROPERTY(EditDefaultsOnly, Category = "BlocksDatabase") TArray<class UMaterialInterface *> BlockMaterials; FORCEINLINE TSubclassOf<class ADreampaxBuildingBlock> * GetBuildingBlockClass() { return &BuildingBlockClass; } FORCEINLINE FVector GetDefaultSize() { return DefaultSize; } FORCEINLINE FVector GetSizeLimits() { return SizeLimits; } FORCEINLINE TArray<class UMaterialInterface *> GetBlockMaterials() { return BlockMaterials; } };
E o ponto mais importante é a declaração do banco de dados:
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "ItemsDatabase") TMap<FGameplayTag, FItemsDatabase> ItemsDataBase;
Agora você já pode criar nosso Blueprint e preenchê-lo.
Exemplo de preenchimento DataAsset Mas antes disso, escreveremos mais algumas funções de chamada para poder receber dados do banco de dados.
DreampaxItemsDataAsset.pp Do multiplayer ainda não há nada. Mas este é o primeiro passo que foi dado na direção certa.
No próximo artigo , falarei sobre os métodos de conexão do DataAsset (sim, e qualquer Blueprint ) para leitura de dados em C ++ e mostrarei qual é o mais correto.
Se você tiver dúvidas ou sugestões para divulgar qualquer aspecto com mais detalhes, escreva nos comentários.