UE4 | معدات متعددة اللاعبين # 4 | إنشاء وتوصيل حاوية


في هذه المقالة ، سوف نناقش إنشاء مكون المخزون وربطه بالممثل المطلوب. نظرًا لأن هذا المكون هو ببساطة مستودع للكائنات ومنطق تحميلها / تفريغها ، فلا يوجد فرق في تطبيقه على شخصية أو نوع من الصناديق.


يمكنك إنشاء مكون باستخدام كل من Blueprint و C ++ . أفضل الطريقة الثانية ، لأنني سأستخدم وظيفة C ++ بنشاط.




بادئ ذي بدء ، نقوم بإنشاء بنية خلية لتخزين عنصر واحد. أفضل تخزينه في ملف .h منفصل من أجل الاتصال بحرية عند الضرورة:


StructContainerStack.h
/// 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 to 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 <FItemFactor> 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<FItemFactor> * GetItemFactors() { return &ItemFactors; } void SetItemFactors(TArray<FItemFactor> const & ItemFactorsNew) { if (ItemFactorsNew.Num() > 0) { ItemFactors = ItemFactorsNew; } } }; 

نعم ، تحتوي خلية المخزون لدينا على 3 متغيرات فقط: المعرف والكمية والمعلمات الفريدة. لا أكثر. يمكن نسخ جميع البيانات وحفظها وتنزيلها دون أي مشاكل. لا مواد ، إشارات إلى الممثلين ، إلخ. ليس هنا. يمكن تنزيل جميع المعلومات الإضافية من قاعدة البيانات على DataAsset ، التي تحدثنا عنها سابقًا.


على الأرجح ، لقد لاحظت بالفعل بنية StructItemFactors.h أخرى ، متصلة في البداية. هذا ليس أكثر من مستودع لأية خصائص فريدة للجسم (على شكل عوامة ) ، مثل البلى ، التلف ، إلخ. بمعنى ، الخصائص المتأصلة فقط في هذه النسخة من الموضوع ، ولا يوجد أي شيء آخر هو نفسه. هذه البنية بسيطة للغاية:


StructItemFactors.h
 /// 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(); } } }; 

تجدر الإشارة إلى وظيفة واحدة مثيرة للاهتمام للغاية في الهيكل أعلاه ، والتي تم تصميمها لتبسيط حياتنا بشكل كبير:


 friend bool operator==(const FItemFactor & Lhs, const FItemFactor & Rhs) { return Lhs.ItemFactorTag == Rhs.ItemFactorTag && Lhs.ItemFactor == Rhs.ItemFactor; } 

هذا ليس أكثر من عامل مقارنة == ، والذي يمكننا استخدامه لهذه البنية حتى لا يتم استخراج العناصر لهذا في كل مرة. مريح للغاية.




لذلك ، مع الانتهاء من الهياكل. ننتقل إلى إنشاء المكون:


DreampaxContainerComponent.h
 /// 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<FContainerStack> ContentOfContainer; public: /* Sets default values for this component's properties */ UDreampaxContainerComponent(const FObjectInitializer & ObjectInitializer); /*        ,   ... */ }; 

إذا كان في الكود أعلاه قم بتفعيل الخط


 UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) ) 

ثم يمكنك توصيل هذا المكون مباشرة بمخطط . أفضل القيام بذلك في C ++ . بالنسبة للشخصية ، يبدو كما يلي:


 Inventory = CreateDefaultSubobject<UDreampaxContainerComponent>(TEXT("Inventory")); 

حسنًا ، لصدر مثل هذا:


 ADreampaxActorContainer::ADreampaxActorContainer(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { Container = CreateDefaultSubobject<UDreampaxContainerComponent>(TEXT("Container")); } 

كما ترون ، الفرق هو فقط في أسماء المتغيرات.




في المقالة التالية سأتحدث عن ميزات النسخ المتماثل (بسيطة على الأصابع ) ، والتي ستجعل مخزوننا متعدد اللاعبين حقًا.

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


All Articles