UE4 | Inventory for Multiplayer # 1 | Data Store on DataAsset
UE4 | Inventory for Multiplayer # 2 | Connect Blueprint to C ++
UE4 | Inventory for Multiplayer # 3 | Interaction structure
UE4 | Inventory for Multiplayer # 4 | Creating and connecting a container
UE4 | Inventory for multiplayer # 5 | Information transfer between Server and Client
In the previous article, I explained how to create DataAsset , and why it is so good and convenient. Here we will look at how to access DataAsset , more precisely, the data assigned to it, from Blueprint and C ++ .
Along the way, we will answer the question of accessing any Blueprint from C ++ .
With the interaction of Blueprints, everything is quite transparent.
Due to the fact that we have closed direct access to our database, we cannot simply access it from Blueprint . Pay attention to protected: in the code below.
protected: /* This is the main Database for all Items. It contains constant common variables */ UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "ItemsDatabase") TMap<FGameplayTag, FItemsDatabase> ItemsDataBase;
Those. our storage will be visible only in inherited classes, and this is good, because we have prescribed functions for safe data call.
/* Used in the widget */ UFUNCTION(BlueprintCallable, Category = "ItemDatabase") FORCEINLINE UTexture2D * GetItemIconTexture(const FGameplayTag & ItemNameTag) const;
BlueprintCallable just means that this function can be used in Blueprint . If you read the previous article , you probably noticed that other functions for invoking such an attribute do not have. This is done only because the data they are currently calling is not needed in Blueprint . If you don’t need to know something, don’t be in a hurry to report it.
The next step is to create in any Blueprint a variable of the type of the database created by us (in my case, this is BP_DreampaxItemsDataAsset ).
After that, it is easy to easily remove the assigned texture.
Now consider how to access information in C ++ .
We cannot simply refer to the DreampaxItemsDataAsset class, since it does not contain any information. We need to get access to BP_DreampaxItemsDataAsset .
There are two main methods of how to reach Blueprint .
First, consider the inconvenient way to connect using the ConstructorHelpers crutch. In this case, it is access to the texture.
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); }
The example is taken from the wonderful EpicSurvivalGameSeries project, ideally suited for learning Multiplayer in C ++ . The author has set a goal to show as many methods and techniques of game programming in C ++ as possible.
Why is this method uncomfortable? The same trouble as with DataTable - if you change the name of the Blueprint or location, the file will not be found.
The most preferable is the method in which we declare a variable in the header file, for later assignment in the inherited Blueprint . For the example above, this might look like this:
UPROPERTY(EditDefaultsOnly, Category = "AimPointer") FCanvasIcon CenterDotIcon;
Now, knowing how to access any Blueprint , we can easily connect our database.
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;
As a person almost unfamiliar with C ++ , I broke a lot of copies, trying to figure out how to correctly declare custom variables.
If the goal is to declare a variable of the class created by us, such as
UDreampaxItemsDataAsset * DreampaxItemsDataAsset; // class UDreampaxItemsDataAsset * DreampaxItemsDataAsset;
for me personally, for some time, it was not clear when it is necessary to apply a class , and when not.
Everything turned out to be painfully simple.
Which of these methods is correct - I can not say. If someone explains, I will be grateful.
We make a variable in the C ++ class ADreampaxGameMode , since it is visible only to the server, and everything related to the spawn of objects must go only through the server. This class is the parent for BP_DreampaxGameMode , where we connect our BP_DreampaxItemsDataAsset .
Now all the power of C ++ can be used to work with the data of our database.
In the next article (finally!) We will talk about inventory creation and find out why we cannot do without the already created DataAsset .
If you have questions or requests to disclose any aspect in more detail, please write in the comments.
Source: https://habr.com/ru/post/418951/
All Articles