UE4 C++ InventorySystem Part.3 Chest
やあ
UE4 C++でインベントリシステムを作ろう!
Part.3では、インベントリコンポーネントを持った、アイテムを作ってそれとやりとりできるようにするよ。
前回
Part.3の結果
目次
概要
①プレイヤー : アイテム(宝箱)を拾う
②宝箱 : 拾われた!イベント発生
③宝箱 : インベントリUIを開く
④プレイヤー : インベントリUIを開く
⑤終わり。
宝箱の動作を考える
・拾われたイベントの発生
-> インベントリUIを開く
これだけ!
拾われたイベントの発生、はPickUpableItemBase
クラスを作った時に見たよね。
宝箱の動作の実装
PickUpableItemBase
クラスを継承してChestItemBase
クラスを作成。
宝箱のインベントリUIを表示させるためのUIをつくる
イメージ図
これは宝箱だけじゃなく、例えば、敵を倒したあとに敵からアイテムを奪うみたいな時にも使える。
さらに、商人とアイテムをやり取りするような時にも使える。
WidgetBase
クラスを継承してExchangeInventoryBase
クラスを作る。
ExchangeInventoryBase.h
に追加
// Copyright(C)write by pto8913. 2020. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "UIs/Bases/WidgetBase.h" #include "ExchangeInventoryBase.generated.h" class AInventoryCharacterBase; class UInventoryComponentBase; class UBorder; UCLASS() class INVENTORYSYSTEM_API UExchangeInventoryBase : public UWidgetBase { GENERATED_BODY() private: UPROPERTY(meta = (BindWidget)) UBorder* UpperBorder; UPROPERTY(meta = (BindWidget)) UBorder* LowerBorder; public: UPROPERTY() UWidgetBase* UpperUI; UPROPERTY() UWidgetBase* LowerUI; void OpenUI() override; void CloseUI() override; };
ExchangeInventoryBase.cpp
に追加
// Copyright(C)write by pto8913. 2020. All Rights Reserved. #include "UIs/Bases/ExchangeInventoryBase.h" #include "UIs/Bases/InventoryWidgetBase.h" #include "Characters/Bases/InventoryCharacterBase.h" #include "Components/Bases/InventoryComponentBase.h" #include "Components/Border.h" ////////////////////////////////////// // Init void UExchangeInventoryBase::OpenUI() { UWidgetBase::OpenUI(); UpperBorder->AddChild(UpperUI); LowerBorder->AddChild(LowerUI); } ////////////////////////////////////// // End void UExchangeInventoryBase::CloseUI() { UWidgetBase::CloseUI(); UpperBorder->ClearChildren(); LowerBorder->ClearChildren(); }
宝箱の動作の実装
ChestItemBase.h
// Copyright(C)write by pto8913. 2020. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "Items/Bases/PickUpableItemBase.h" #include "ChestItemBase.generated.h" class UBoxComponent; class UInventoryComponentBase; class UExchangeInventoryBase; UCLASS() class INVENTORYSYSTEM_API AChestItemBase : public APickUpableItemBase { GENERATED_BODY() private: AChestItemBase(); UPROPERTY(VisibleAnywhere) UBoxComponent* BoxCollisionComp; UPROPERTY(VisibleAnywhere) UInventoryComponentBase* InventoryComp; private: /* UIs */ UPROPERTY() UExchangeInventoryBase* ExchangeInventoryUI; /* Classes */ UPROPERTY(EditAnywhere) TSubclassOf<UExchangeInventoryBase> ExchangeInventoryUIClass; public: virtual bool PickUp(AInventoryCharacterBase* In) override; };
ChestItemBase.cpp
// Copyright(C)write by pto8913. 2020. All Rights Reserved. #include "Items/Bases/ChestItemBase.h" #include "UIs/Bases/ExchangeInventoryBase.h" #include "UIs/Bases/InventoryWidgetBase.h" #include "Characters/Bases/InventoryCharacterBase.h" #include "Components/Bases/InventoryComponentBase.h" #include "Components/BoxComponent.h" #include "Components/TextBlock.h" AChestItemBase::AChestItemBase() { BoxCollisionComp = CreateDefaultSubobject<UBoxComponent>(TEXT("Collision Comp")); BoxCollisionComp->SetupAttachment(RootComponent); InventoryComp = CreateDefaultSubobject<UInventoryComponentBase>(TEXT("Chest Comp")); InventoryComp->NumberOfSlots = 12; } bool AChestItemBase::PickUp(AInventoryCharacterBase* In) { if (InventoryComp->Inventory.Num() == 0) { InventoryComp->Init(); } if (IsValid(ExchangeInventoryUI) == true) { /* Close */ InventoryComp->ToggleInventory(); In->InventoryComp->ToggleInventory(); In->bIsTalking = false; ExchangeInventoryUI->CloseUI(); In->InventoryHUD->ExchangeBorder->SetRenderOpacity(0.f); In->InventoryHUD->ExchangeBorder->ClearChildren(); ExchangeInventoryUI = nullptr; } else { ExchangeInventoryUI = CreateWidget<UExchangeInventoryBase>( GetWorld(), ExchangeInventoryUIClass ); if (IsValid(ExchangeInventoryUI) == true) { InventoryComp->ToggleInventory(); ExchangeInventoryUI->UpperUI = InventoryComp->InventoryUI; In->bIsTalking = true; In->InventoryComp->ToggleInventory(); ExchangeInventoryUI->LowerUI = In->InventoryComp->InventoryUI; ExchangeInventoryUI->OpenUI(); InventoryComp->InventoryUI->InventoryName->SetText(FText::FromString("Chest")); In->InventoryHUD->ExchangeBorder->SetRenderOpacity(1.f); In->InventoryHUD->ExchangeBorder->AddChild(ExchangeInventoryUI); } } return true; }
エディタに戻って
ExchangeInventoryBase
クラスを継承して、WBP_ExchangeInventory
を作成。
ChestItemBase
クラスを継承して、BP_ChestItem
を作成。
今回は簡単にするため、二枚目の画像でインベントリにアイテムを手動で登録していますが、実際に使う際はランダムに決めたり、データテーブルで管理してください。
今回はここまで