UE求职Demo开发日志#18 数据表获取物品信息,添加背包模块

1 把获取物品信息改为读取数据表

先创建结构,暂时有这几个属性:

USTRUCT(BlueprintType)
struct ARPG_CPLUS_API FMyItemData:public FTableRowBase
{
	GENERATED_USTRUCT_BODY()
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	int ItemId;//物品Id,唯一
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	int MaxOwnedCnt;//最大堆叠数量
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FString ItemBaseName;//物品名称
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	UTexture2D* Texture;//物品图标
};

 创建对应的数据表

实现Get函数:

FMyItemData UWarehouseManager::GetItemDataByItemId(int ItemId)
{
	if(!ItemDataTable)return FMyItemData();
	// 获取DataTable的所有行
	TArray<FName> RowNames= ItemDataTable->GetRowNames();

	// 遍历每一行
	for (const auto& RowName : RowNames)
	{
		FMyItemData* RowData = ItemDataTable->FindRow<FMyItemData>(RowName,FString(""),true);

		if (RowData->ItemId == ItemId)
		{
			return *RowData;
		}
	}
	return FMyItemData();
}

把原来获取Texture的地方改为用这个函数:

 2 编写Bag相关代码

2.1 BagSaveData

//BagSaveData.h
#pragma once

#include "CoreMinimal.h"
#include "GameFramework/SaveGame.h"
#include "BagSaveData.generated.h"

struct FMyItemInfo;
/**
 * 
 */
UCLASS()
class ARPG_CPLUS_API UBagSaveData : public USaveGame
{
	GENERATED_BODY()
public:
	UBagSaveData();
	UFUNCTION(BlueprintCallable)
	TArray<FMyItemInfo> GetItemsInBag();
	UFUNCTION(BlueprintCallable)
	void SetItemsInBag(TArray<FMyItemInfo> InItems);
	
private:
	UPROPERTY(EditDefaultsOnly)
	TArray<FMyItemInfo> ItemsInBag;
};
//BagSaveData.cpp
#include "Items/BagSaveData.h"
#include "Items/WarehouseManager.h"

UBagSaveData::UBagSaveData()
{
	
}

TArray<FMyItemInfo> UBagSaveData::GetItemsInBag()
{
	return ItemsInBag;
}

void UBagSaveData::SetItemsInBag(TArray<FMyItemInfo> InItems)
{
	ItemsInBag = InItems;
}

2.2 BagManager

//BagManager.h
#pragma once

#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "BagManager.generated.h"


struct FMyItemInfo;

UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class ARPG_CPLUS_API UBagManager : public UActorComponent
{
	GENERATED_BODY()

public:	
	// Sets default values for this component's properties
	UBagManager();
	UFUNCTION(BlueprintCallable)
	void SaveData();
	UFUNCTION(BlueprintCallable)
	void LoadData();
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "BagItemData")
	UDataTable* ItemDataTable;

	UPROPERTY(BlueprintReadOnly)
	TArray<FMyItemInfo> ItemsInBag;

	UFUNCTION(BlueprintCallable)
	void LogMes();
	UFUNCTION(BlueprintCallable)
	void AddItemByArray(TArray<FMyItemInfo> ItemsToAdd);
	UFUNCTION(BlueprintCallable)
	void AddItemToBag(FMyItemInfo& ItemToAdd);
	UFUNCTION(BlueprintCallable)
	bool RemoveItemFromBag(int ItemId,int Subcnt);
	UFUNCTION(BlueprintCallable)
	FMyItemInfo GetItemInfoByItemId(int ItemId);

protected:
	// Called when the game starts
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
};
//BagManager.cpp
#include "Items/BagManager.h"

#include "Items/BagSaveData.h"
#include "Items/WarehouseManager.h"
#include "Kismet/GameplayStatics.h"

// Sets default values for this component's properties
UBagManager::UBagManager()
{
	// Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these features
	// off to improve performance if you don't need them.
	PrimaryComponentTick.bCanEverTick = true;
	//UE_LOG(LogTemp,Warning,TEXT("UBagManager Construct Start"));
	LoadData();
	//LogMes();
	static ConstructorHelpers::FObjectFinder<UDataTable> DataTableAsset(TEXT("DataTable'/Game/Data/DataTable/ItemsData.ItemsData'"));
	if (DataTableAsset.Succeeded())
	{
		ItemDataTable = DataTableAsset.Object;
		//UE_LOG(LogTemp,Warning,TEXT("Item DataTable Load Success"));
	}
	//UE_LOG(LogTemp,Warning,TEXT("UBagManager Construct End"));
	// ...
}


// Called when the game starts
void UBagManager::BeginPlay()
{
	Super::BeginPlay();
	LoadData();
}


// Called every frame
void UBagManager::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
}
void UBagManager::SaveData()
{
	UBagSaveData* Save = Cast<UBagSaveData>(UGameplayStatics::CreateSaveGameObject(UBagSaveData::StaticClass()));
	if (Save)
	{
		Save->SetItemsInBag(ItemsInBag);
		if (UGameplayStatics::SaveGameToSlot(Save, FString("BagSaveData"), 0))
		{
			UE_LOG(LogTemp, Warning, TEXT("UBagManager-->Save Success"));
		}
		else
		{
			UE_LOG(LogTemp, Warning, TEXT("UBagManager-->Save Failed"));
		}
	}
}
void UBagManager::LoadData()
{
	bool bIsExistSaveData=UGameplayStatics::DoesSaveGameExist(FString("BagSaveData"),0);
	
	if(bIsExistSaveData)
	{
		UBagSaveData* save=Cast<UBagSaveData>(UGameplayStatics::LoadGameFromSlot(FString("BagSaveData"), 0));
		ItemsInBag=save->GetItemsInBag();
		UE_LOG(LogTemp,Warning,TEXT("UBagManager-->Loaded Success"));
	}else
	{
		SaveData();
		UE_LOG(LogTemp,Warning,TEXT("UBagManager-->Loaded Fail"));
	}
}


void UBagManager::LogMes()
{
	UE_LOG(LogTemp, Warning, TEXT("BagManager::LogMes-->Start,Num==%d"),ItemsInBag.Num());
	for(FMyItemInfo& bagItem : ItemsInBag)
	{
		UE_LOG(LogTemp, Warning, TEXT("ID==%d CurrentOwnedCnt==%d DisplayName==%s"), bagItem.ItemId, (int)bagItem.CurrentOwnedCnt,*bagItem.DisplayName);
	}
}

void UBagManager::AddItemByArray(TArray<FMyItemInfo> ItemsToAdd)
{
	for(FMyItemInfo& bagItem : ItemsToAdd)
	{
		AddItemToBag(bagItem);
	}
	SaveData();
}

void UBagManager::AddItemToBag(FMyItemInfo& ItemToAdd)
{
	bool bisFind=false;
	for(FMyItemInfo& bagItem : ItemsInBag)
	{
		if(bagItem.ItemId == ItemToAdd.ItemId)
		{
			//TODO:限制最大堆叠
			bagItem.CurrentOwnedCnt += ItemToAdd.CurrentOwnedCnt;
			bisFind=true;
			break;
		}
	}
	if(!bisFind)
	{
		ItemsInBag.Add(ItemToAdd);
	}
	SaveData();
}

bool UBagManager::RemoveItemFromBag(int ItemId,int Subcnt)
{
	for(FMyItemInfo& bagItem : ItemsInBag)
	{
		if(bagItem.ItemId == ItemId)
		{
			if(bagItem.CurrentOwnedCnt>Subcnt)
			{
				bagItem.CurrentOwnedCnt-=Subcnt;
				SaveData();
				UE_LOG(LogTemp, Warning, TEXT("UBagManager::RemoveItemFromBag Success! Cnt==%d"),(int)bagItem.CurrentOwnedCnt);
				return true;//如果数量够的话就直接减
			}
		}
	}
	SaveData();
	UE_LOG(LogTemp, Warning, TEXT("UBagManager::RemoveItemFromBag not Enough"));
	return false;
}

FMyItemInfo UBagManager::GetItemInfoByItemId(int ItemId)
{
	for(FMyItemInfo& bagItem : ItemsInBag)
	{
		if(bagItem.ItemId == ItemId)
		{
			//LogMes();
			//UE_LOG(LogTemp,Warning,TEXT("GetItemInfoByItemId-->ItemId==%d,CurrentCnt==%d"),ItemId,(int)bagItem.CurrentOwnedCnt);
			return bagItem;
		}
	}
	return FMyItemInfo();
}

3  制作BagUI,动态生成物品格子

        动态生成25个(测试用),5行5列,生成时设置行列填充比例都为1,这样GridPanel就能平均分配空间

添加到子项: 

根据是否有数据来选择是否更新信息: 

 

更新信息: 

 效果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值