UE求职Demo开发日志#16 实现物品合成表读取和合成逻辑
1 搭建交互Trigger(跟主题无关,一个小改动)
添加枚举定义:
UENUM(BlueprintType)
enum class EMyInterActType : uint8
{
None=0,
OpenStrengthenPad UMETA(DisplayName = "OpenStrengthenPad"),
OpenWareHousePad UMETA(DisplayName = "OpenWareHousePad"),
PickUpProp UMETA(DisplayName = "PickUpProp"),
};
在角色类里添加变量记录当前应该响应的类型:
//交互相关
UPROPERTY(EditDefaultsOnly,BlueprintReadWrite,Category = "MyPlayer|InterAct")
EMyInterActType CurrentInterActType=EMyInterActType::None;
在交互时要关闭某些功能的时候,添加对应的逻辑,例如:
if(CurrentInterActType!=EMyInterActType::None)return;
新建一个Actor放置在场景里,添加重叠事件:
角色蓝图里的响应逻辑整合一下:
2 搭建合成表信息显示UI (未绑定数据)
空面板:
将要动态生成的单元:
3 创建UInventoryManager
UInventoryManager现在继承的是Actor组件类,以后可能会改
3.1 创建行结构继承FTableRowBase
USTRUCT(BlueprintType)
struct FRecipeRow : public FTableRowBase
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadOnly)
int32 RecipeId;
UPROPERTY(EditAnywhere, BlueprintReadOnly)
TArray<FMyItemInfo> RequiredMaterials;
UPROPERTY(EditAnywhere, BlueprintReadOnly)
FMyItemInfo ResultItem;
};
3.2 两个工具函数,一个读取数据表行,一个执行合成逻辑
UFUNCTION(BlueprintCallable)
FRecipeRow GetRecipeRowById(int RecipeId);
UFUNCTION(BlueprintCallable)
bool CraftItem(int RecipeId);
实现:
WarehouseManager的引用先在BeginPlay中设置,先将组件放在Player身上测试
其中打印信息的函数是测试用的
FRecipeRow UInventoryManager::GetRecipeRowById(int RecipeId)
{
TArray<FName> RowNames= RecipeDataTable->GetRowNames();
for (const auto& RowName : RowNames)
{
FRecipeRow* RowData = RecipeDataTable->FindRow<FRecipeRow>(RowName,FString(""),true);
if (RowData->RecipeId == RecipeId)
{
return *RowData;
}
}
return FRecipeRow();
}
bool UInventoryManager::CraftItem(int RecipeId)
{
FRecipeRow Recipe = GetRecipeRowById(RecipeId);
if (Recipe.RecipeId==0) return false;
if(!WarehouseManager)return false;
WarehouseManager->LogMes();
for (const FMyItemInfo& Material : Recipe.RequiredMaterials)
{
if (!WarehouseManager->RemoveItemFromWarehouse(Material.ItemId, Material.CurrentOwnedCnt))
{
return false; // 某种材料不足,合成失败
}
}
WarehouseManager->AddItemToWarehouse(Recipe.ResultItem.ItemId, Recipe.ResultItem.CurrentOwnedCnt, Recipe.ResultItem.DisplayName);
WarehouseManager->LogMes();
return true;
}
在数据表中设置测试用的第一行:
调用测试:
测试结果:
数据层面是对的,DisplayName先不用管,逻辑还没完善