参照教程 https://wiki.unrealengine.com/index.php?title=C%2B%2B_Inventory#Player_Controller
最后ui提示部分没有做 只是在代码中简单的进行了一下输出
整体结构
1.首先创建物品的DataTable类型
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Engine/UserDefinedStruct.h"
#include "Engine/DataTable.h"
#include "InventoryItem.generated.h"
/**
*
*/
USTRUCT()
struct INVENTORY_API FInventoryItem : public FTableRowBase
{
GENERATED_BODY()
public:
FInventoryItem()
{
this->Name = FText::FromString("No Name");
this->Weight = 1;
this->Value = 1;
this->Description = FText::FromString("No Description");
}
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FName ItemID;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FText Name;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
int32 Weight;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
int32 Value;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
UTexture2D* Thumbnail;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FText Description;
bool operator==(const FInventoryItem& OtherItem) const
{
if (ItemID == OtherItem.ItemID)
return true;
return false;
}
};
2.在工程中创建DataTable资源 后面会在GameState中进行加载
3.创建可以拾取的物体 一共分为两种类型 一种是通过按键拾取的Interactable 一种是根据角色碰撞盒进行检测的AutoPickup
就不具体展开了 可以看后面的工程源码
4.创建PlayerController GameState 在GameState中加载我们刚才创建的Datatable资源
// Fill out your copyright notice in the Description page of Project Settings.
#include "InventoryGameState.h"
AInventoryGameState::AInventoryGameState()
{
static ConstructorHelpers::FObjectFinder<UDataTable> BP_ItemDB(TEXT("DataTable'/Game/Item/ItemListDT.ItemListDT'"));
ItemDB = BP_ItemDB.Object;
}
UDataTable* AInventoryGameState::GetItemDB() const
{
return ItemDB;
}
PlayerController中对拾取到的物品进行重量或者容量的判断 然后进行保存
扫描二维码关注公众号,回复:
9832994 查看本文章
5.在Character中 对两种不同类型的物品进行检测 是否可拾取 然后调用Controller保存
void AInventoryCharacter::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
CollectAutoPickups();
CheckForInteractables();
}
void AInventoryCharacter::CollectAutoPickups()
{
TArray<AActor*> CollectedActors;
CollectionSphere->GetOverlappingActors(CollectedActors);
AInventoryController* IController = Cast<AInventoryController>(GetController());
for (int32 i = 0; i < CollectedActors.Num(); i++)
{
AAutoPickup* Pick = Cast<AAutoPickup>(CollectedActors[i]);
if (Pick && !Pick->IsPendingKill())
{
Pick->Collect(IController);
}
}
}
void AInventoryCharacter::CheckForInteractables()
{
FHitResult HitResult;
int32 Range = 500;
FVector StartTrace = FollowCamera->GetComponentLocation();
FVector EndTrace = (FollowCamera->GetForwardVector() * Range) + StartTrace;
FCollisionQueryParams QueryParams;
QueryParams.AddIgnoredActor(this);
AInventoryController* IController = Cast<AInventoryController>(GetController());
if (IController)
{
if (GetWorld()->LineTraceSingleByChannel(HitResult, StartTrace, EndTrace, ECC_Visibility, QueryParams))
{
AInteractable* Interactable = Cast<AInteractable>(HitResult.GetActor());
if (Interactable)
{
IController->CurrentInteractable = Interactable;
return;
}
}
IController->CurrentInteractable = nullptr;
}
}
6.最后在GameMode中使用我们自定义的Controller和GameState 然后在工程中对拾取的按键进行配置
AInventoryGameMode::AInventoryGameMode()
{
// set default pawn class to our Blueprinted character
static ConstructorHelpers::FClassFinder<APawn> PlayerPawnBPClass(TEXT("/Game/ThirdPersonCPP/Blueprints/ThirdPersonCharacter"));
if (PlayerPawnBPClass.Class != NULL)
{
DefaultPawnClass = PlayerPawnBPClass.Class;
PlayerControllerClass = AInventoryController::StaticClass();
GameStateClass = AInventoryGameState::StaticClass();
}
}