Dans cet article, je vais essayer de révéler le sens et la méthodologie de la création de DataAsset , en tant que référentiel pour différents types de données, et dans notre cas, c'est une bibliothèque pour les acteurs et leurs paramètres.
Une petite introduction à sauterPour prendre la décision de créer un jeu il y a environ 2 ans, cela m'a aidé à tomber par hasard sur des informations sur Unreal Engine 4 et à lire à quel point c'est cool et simple. En fait, il est très difficile pour une personne qui ne sait pas écrire du code (un langage de programmation n'a pas d'importance dans ce contexte) de créer quelque chose de plus compliqué qu'une petite modification d'un ensemble standard de pièces à partir du moteur. Par conséquent, le désir initial de faire un super-méga jeu, avec la croissance des connaissances sur la réalité de ce projet, est progressivement devenu un passe-temps. Augmenter toutes les couches de développement de jeux, de la modélisation et de l'animation 3D à l'écriture de code, pour une personne semble une entreprise peu réalisable. Cependant, c'est un bon entraînement pour le cerveau.
Pourquoi avez-vous décidé d'écrire quelque chose? .. Probablement à cause de cela. que les manuels présentés donnent soit des connaissances très superficielles (et il y en a la plupart), soit même pour un très professionnel et ne contiennent que des instructions générales.
Il vaut presque toujours mieux recommencer depuis le début. Je ne peux pas dire que je fais toujours ça, mais je vais essayer de dire le plus systématiquement possible.
Bien sûr, il est préférable de commencer par la structure, mais, malheureusement, ayant une boîte fermée avec des outils, il est très difficile de comprendre ce qui peut être construit exactement avec leur aide. Ouvrons donc cette boîte et voyons ce qu'il y a à l'intérieur.
La première question à laquelle répondre. Pourquoi DataAsset ?
- Très souvent, dans les articles et les didacticiels, vous pouvez voir l'utilisation de DataTable . Pourquoi est-ce mauvais? Si vous stockez une adresse pour un Blueprint spécifique, lors du changement de nom ou du déplacement vers un autre dossier, vous serez obligé de modifier cette adresse manuellement. D'accord - mal à l'aise? Avec DataAsset , cela ne se produira pas. Toutes les communications seront mises à jour automatiquement. Si vous êtes absolument confiant dans la structure de votre projet pour les années à venir, vous pouvez bien sûr utiliser des tableaux.
- Le deuxième avantage indéniable est la possibilité de stocker des types de données complexes, tels que des structures ( Struct ).
Maintenant, un peu sur les inconvénients relatifs. En fait, je n'en vois qu'un. C'est la nécessité d'écrire du code C ++ .
Si vous comprenez déjà que sans travailler avec le code, vous ne ferez rien d' épique , alors ce n'est pas un inconvénient, mais une fonctionnalité.
Il convient de noter qu'il existe une solution de contournement: utiliser Actor en tant que tel référentiel. Mais une telle application ressemble à la dernière excuse pour ne pas vouloir apprendre le C ++ et détient le potentiel de se retrouver dans une impasse à l'avenir.
Si vous êtes convaincu que tout ce dont vous avez besoin pour votre projet peut être fait sur Blueprint , utilisez les tableaux.
Maintenant que vous avez déjà cru que DataAsset est bon, réfléchissez à la manière de le créer pour votre projet.
Pour ceux qui ne sont toujours pas dans le réservoirIl y a une description très détaillée des étapes et des photos sur le forum de langue russe dédié à UE4 . Il suffit de google "UE4 DataAsset" pour . Il a maîtrisé les bases de ce manuel il y a environ un an.
Tout d'abord, créez une classe C ++ , comme Child à partir d' UDataAsset .
(Tout le code ci-dessous est tiré de mon projet à naître. Renommez simplement les noms comme vous le souhaitez.)
Maintenant, sur la base de cette classe, vous pouvez créer Blueprint en toute sécurité, mais il est trop tôt pour le faire ... jusqu'à présent, c'est juste un mannequin. Cependant, notez que des inclusions pour les textures et les noms ont déjà été faites.
A partir de ce moment, vous commencez à créer la structure de votre référentiel. Il sera refait plusieurs fois, donc je recommande fortement de ne pas immédiatement remplir votre espace de stockage. Trois à cinq éléments, dans notre cas les éléments d'inventaire, suffisent pour les tests. Parfois, après la compilation, votre Blueprint peut être vierge vide, ce qui est extrêmement désagréable si vous avez déjà rempli une douzaine ou deux postes.
Vous pouvez créer une structure directement dans le fichier d'en-tête, car dans ce cas, il est peu probable qu'il soit appliqué ailleurs. Habituellement, je préfère le faire en tant que fichier d'en-tête séparé "SrtuctName.h" , et le connecter si nécessaire selon les besoins.
Dans mon cas, ça ressemble à ça 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;
Soyez des comptes avec TMap . Pas répliqué! Dans ce cas, cela n'a pas d'importance.
Veuillez noter que je n'utilise pas FName . Selon les tendances modernes, l'utilisation de FGameplayTag est considérée comme plus correcte, car réduit considérablement le risque d'erreur et présente plusieurs avantages qui vous seront utiles ultérieurement.
GameplayTag dans l'éditeur DataTable pour GameplayTag exporté depuis Excel Il est également recommandé de définir des fonctions pour appeler des variables dans la structure, telles que GetSomething () . Apparemment, j'ai encore besoin de travailler sur mon éducation, car c'est dans cette base de données, je n'ai pas encore fait un tel appel.
Voici comment cela peut être fait en utilisant une autre base de données comme exemple. 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; } };
Et le point le plus important est la déclaration de la base de données:
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "ItemsDatabase") TMap<FGameplayTag, FItemsDatabase> ItemsDataBase;
Vous pouvez maintenant déjà créer notre Blueprint et le remplir.
Exemple de remplissage DataAsset Mais avant cela, nous écrirons quelques fonctions d'appel supplémentaires afin de pouvoir recevoir des données de la base de données.
DreampaxItemsDataAsset.pp Du multijoueur il n'y a toujours rien. Mais c'est le premier pas qui a été fait dans la bonne direction.
Dans le prochain article, je parlerai des méthodes de connexion de DataAsset (oui, et de tout Blueprint ) pour lire les données en C ++, et montrer laquelle est la plus correcte.
Si vous avez des questions ou des suggestions pour divulguer un aspect plus en détail, veuillez écrire dans les commentaires.