UE4 | Inventory for Multiplayer # 4 | Creation and connection of the koiner

List of articles [/b]
UE4 | Inventory for Multiplayer # 1 | Data warehouse on the DataAsset
 
UE4 | Inventory for Multiplayer # 2 | Connecting Blueprint to C ++
 
UE4 | Inventory for Multiplayer # 3 | Structure of the interaction
 
UE4 | Inventory for Multiplayer # 4 | Creation and connection of the coneer
 
UE4 | Inventory for Multiplayer # 4 | Creation and connection of the koiner In this article, we'll discuss creating an inventory component and connecting it to the required Actor. Since this component is simply a store of objects and the logic of their loading /unloading, there is no difference in applying it to a character or some kind of box.
 
You can create a component using
Blueprint
, so with
C ++
. I prefer the second method, because I'm going to actively use the functional
C ++
.
 
 
First of all, we create a cell structure for storing one object. I prefer to store it in a separate
.h
file, in order to freely connect where necessary, where necessary: ​​
 
StructContainerStack.h [/b]
///Copyright 2018 Dreampax Games, Inc. All Rights Reserved.
/* Struct for Container Stack. This file is used as #include * /
#pragma once
/* Includes from Engine * /
#include "GameplayTagContainer.h"
/* Includes from Dreampax * /
#include "Data /StructItemFactors.h"
#include "StructContainerStack.generated.h"
/* Declaration for contaiter stack structure. BlueprintType required for use in BP * /
USTRUCT (BlueprintType)
struct FContainerStack
{
GENERATED_USTRUCT_BODY ()
/* Gameplay tag to store the name * /
UPROPERTY (EditAnywhere)
FGameplayTag ItemNameTag;
UPROPERTY (EditAnywhere)
int ItemAmount;
/* Specific factors such as durability, damage etc. * /
UPROPERTY (EditAnywhere)
TArray
ItemFactors;
FContainerStack ()
{
Clear ();
}
void Clear ()
{
ItemNameTag.FromExportString ("NAME_None");
ItemAmount = 0;
ItemFactors.Empty ();
}
FORCEINLINE FGameplayTag GetItemNameTag () const
{
return ItemNameTag;
}
void SetItemNameTag (FGameplayTag const & ItemNameTagNew)
{
if (ItemNameTagNew.IsValid ())
{
ItemNameTag = ItemNameTagNew;
}
else
{
Clear ();
}
}
FORCEINLINE int GetItemAmount () const
{
return ItemAmount;
}
void SetItemAmount (int const & ItemAmountNew)
{
if (ItemAmountNew> 0)
{
ItemAmount = ItemAmountNew;
}
else
{
Clear ();
}
}
FORCEINLINE TArray
* GetItemFactors ()
{
return & ItemFactors;
}
void SetItemFactors (TArray
const & ItemFactorsNew)
{
if (ItemFactorsNew.Num ()> 0)
{
ItemFactors = ItemFactorsNew;
}
}
};};

 
Yes, our inventory cell contains only 3 variables: identifier, quantity and unique parameters. Nothing extra. All data can be copied, saved and loaded without problems. No textures, links to
Actors
etc. there is not. All additional information can be downloaded from the database at
DataAsset
, about which we spoke earlier.
 
Most likely, you already paid attention to another structure of
StructItemFactors.h
, connected in the beginning. This is nothing more than a repository of any unique properties of the object (in the form of
float
), Such as wear, damage, etc. That is, the properties that are inherent only in this copy of the subject, and no other is the same. This structure is very simple:
 
StructItemFactors.h [/b]
///Copyright 2018 Dreampax Games, Inc. All Rights Reserved.
/* Struct for Factors. This file is used as #include * /
#pragma once
/* Includes from Engine * /
#include "GameplayTagContainer.h"
/* Includes from Dreampax * /
//no includes
#include "StructItemFactors.generated.h"
USTRUCT (BlueprintType)
struct FItemFactor
{
GENERATED_USTRUCT_BODY ()
/* Name of Item Attribute Factor * /
UPROPERTY (EditDefaultsOnly, Category = "ItemsDatabase")
FGameplayTag ItemFactorTag;
/* Factor for the Item Attribute * /
UPROPERTY (EditDefaultsOnly, Category = "ItemsDatabase")
float ItemFactor;
/* for this type to be comparable * /
friend bool operator == (const FItemFactor & Lhs, const FItemFactor & Rhs)
{
return Lhs.ItemFactorTag == Rhs.ItemFactorTag && Lhs.ItemFactor == Rhs.ItemFactor;
}
FItemFactor ()
{
Clear ();
}
void Clear ()
{
ItemFactorTag.EmptyTag;
ItemFactor = 0;
}
FORCEINLINE FGameplayTag GetItemFactorTag ()
{
return ItemFactorTag;
}
void SetItemFactorTag (FGameplayTag const & ItemFactorTagNew)
{
if (ItemFactorTagNew.IsValid ())
{
ItemFactorTag = ItemFactorTagNew;
}
else
{
Clear ();
}
}
FORCEINLINE float GetItemFactor ()
{
return ItemFactor;
}
void SetItemFactor (float const & ItemFactorNew)
{
if (ItemFactorNew> 0.0f)
{
ItemFactor = ItemFactorNew;
}
else
{
Clear ();
}
}
};};

 
It is worth noting one very interesting function in the structure above, which is designed to significantly simplify our life:
 
friend bool operator == (const FItemFactor & Lhs, const FItemFactor & Rhs)
{
return Lhs.ItemFactorTag == Rhs.ItemFactorTag && Lhs.ItemFactor == Rhs.ItemFactor;
}

 
This is nothing more than a comparison operator
==
, which we can use for this structure, so that we do not extract the elements for this every time. Very comfortably.
 
 
So, with the structures finished. Now we are going to create the component:
 
DreampaxContainerComponent.h [/b]
///Copyright 2018 Dreampax Games, Inc. All Rights Reserved.
#pragma once
/* Includes from Engine * /
#include "Components /ActorComponent.h"
#include "GameplayTagContainer.h"
/* Includes from Dreampax * /
#include "Data /StructItemFactors.h"
#include "Data /StructContainerStack.h"
#include "DreampaxContainerComponent.generated.h"
//UCLASS (ClassGroup = (Custom), meta = (BlueprintSpawnableComponent)) //currently not required
UCLASS ()
class DREAMPAX_API UDreampaxContainerComponent: public UActorComponent
{
GENERATED_BODY ()
private:
UPROPERTY (Transient, Replicated, EditAnywhere, Category = "Container")
TArray
ContentOfContainer;
public:
/* Sets default values ​​for this component's properties * /
UDreampaxContainerComponent (const FObjectInitializer & ObjectInitializer);
/*
Then there are the functions for obtaining data from the component,
replication, etc
* /
};};

 
If the code above activates the line
 
UCLASS (ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
 
then you can connect this component directly to
Blueprint
. I prefer to do it in
C ++
. For
Character
it looks like this:
 
Inventory = CreateDefaultSubobject
(TEXT ("Inventory"));

 
Well, for some trunk like this:
 
ADreampaxActorContainer :: ADreampaxActorContainer (const FObjectInitializer & ObjectInitializer)
: Super (ObjectInitializer)
{
Container = CreateDefaultSubobject
(TEXT ("Container"));
}

 
As you can see, the only difference is in the names of the variables.
 
 
In the next article, I'll talk about the features of replication (by simple
on fingers
), Which will make our inventory really multiplayer.
+ 0 -

Add comment