Building Cost Types¶
本页说明建筑成本系统使用的公共数据类型,包括成本目标、成本条目、运行时上下文、执行结果和 UI 数据。
类型关系¶
FBuildingCostEntry
└── Costs
└── FBuildingCostTargetAmount
└── TargetData
└── FBuildingCostTargetBase 派生类型
UBuildingCostEvaluator
├── CanAfford
├── Consume
└── EvaluateForUI
UBuildingCostSet
└── CostEntries
└── FBuildingCostEntry
成本目标类型¶
成本目标用于标识 Evaluator 需要检查或消耗的资源、货币或物品。
所有成本目标均继承自:
FBuildingCostTargetBase¶
成本目标的基础结构,本身不包含数据。
项目可以继承该结构,创建自定义成本目标类型。
内置目标类型¶
| 类型 | 字段 | 数据类型 | 说明 |
|---|---|---|---|
FBuildingCostTarget_Name |
Name |
FName |
使用名称标识目标。 |
FBuildingCostTarget_IntId |
Id |
int32 |
使用整数 ID 标识目标。 |
FBuildingCostTarget_GameplayTag |
Tag |
FGameplayTag |
使用 Gameplay Tag 标识目标。 |
FBuildingCostTarget_PrimaryAssetId |
AssetId |
FPrimaryAssetId |
使用 Primary Asset ID 标识目标。 |
FBuildingCostTarget_SoftObject |
Asset |
TSoftObjectPtr<UObject> |
使用软对象引用标识目标。 |
FBuildingCostTarget_Name¶
USTRUCT(BlueprintType)
struct FBuildingCostTarget_Name
: public FBuildingCostTargetBase
{
GENERATED_BODY()
UPROPERTY(
EditAnywhere,
BlueprintReadOnly,
Category = "Building|Cost"
)
FName Name = NAME_None;
};
适合使用资源名称或项目自定义名称作为标识。
FBuildingCostTarget_IntId¶
USTRUCT(BlueprintType)
struct FBuildingCostTarget_IntId
: public FBuildingCostTargetBase
{
GENERATED_BODY()
UPROPERTY(
EditAnywhere,
BlueprintReadOnly,
Category = "Building|Cost"
)
int32 Id = INDEX_NONE;
};
适合使用数据库 ID、物品 ID 或资源编号的项目。
FBuildingCostTarget_GameplayTag¶
USTRUCT(BlueprintType)
struct FBuildingCostTarget_GameplayTag
: public FBuildingCostTargetBase
{
GENERATED_BODY()
UPROPERTY(
EditAnywhere,
BlueprintReadOnly,
Category = "Building|Cost"
)
FGameplayTag Tag;
};
例如:
FBuildingCostTarget_PrimaryAssetId¶
USTRUCT(BlueprintType)
struct FBuildingCostTarget_PrimaryAssetId
: public FBuildingCostTargetBase
{
GENERATED_BODY()
UPROPERTY(
EditAnywhere,
BlueprintReadOnly,
Category = "Building|Cost"
)
FPrimaryAssetId AssetId;
};
适合使用 Unreal Engine Primary Asset 系统管理物品或资源。
FBuildingCostTarget_SoftObject¶
USTRUCT(BlueprintType)
struct FBuildingCostTarget_SoftObject
: public FBuildingCostTargetBase
{
GENERATED_BODY()
UPROPERTY(
EditAnywhere,
BlueprintReadOnly,
Category = "Building|Cost"
)
TSoftObjectPtr<UObject> Asset;
};
软引用不保证目标资产已经加载,Evaluator 应根据项目需求处理加载。
FBuildingCostTargetAmount¶
FBuildingCostTargetAmount 表示一项成本目标和对应数量。
USTRUCT(BlueprintType)
struct FBuildingCostTargetAmount
{
GENERATED_BODY()
UPROPERTY(
EditAnywhere,
BlueprintReadOnly,
Category = "Building|Cost"
)
bool bEnabled = true;
UPROPERTY(
EditAnywhere,
BlueprintReadOnly,
Category = "Building|Cost"
)
TInstancedStruct<FBuildingCostTargetBase> TargetData;
UPROPERTY(
EditAnywhere,
BlueprintReadOnly,
Category = "Building|Cost",
meta = (ClampMin = "0")
)
int32 Amount = 1;
UPROPERTY(
EditAnywhere,
BlueprintReadOnly,
Category = "Building|Cost|UI"
)
FText DisplayName;
UPROPERTY(
EditAnywhere,
BlueprintReadOnly,
Category = "Building|Cost|UI"
)
TObjectPtr<UTexture2D> Icon = nullptr;
};
| 字段 | 数据类型 | 默认值 | 说明 |
|---|---|---|---|
bEnabled |
bool |
true |
是否启用当前成本目标。 |
TargetData |
TInstancedStruct<FBuildingCostTargetBase> |
空 | 当前目标的具体数据。 |
Amount |
int32 |
1 |
需要检查或消耗的数量。 |
DisplayName |
FText |
空 | 可选的 UI 名称覆盖。 |
Icon |
UTexture2D* |
nullptr |
可选的 UI 图标覆盖。 |
TargetData 只能选择继承自 FBuildingCostTargetBase 的结构。
例如:
| Target Data 类型 | 示例 |
|---|---|
FBuildingCostTarget_GameplayTag |
Resource.Wood |
FBuildingCostTarget_IntId |
1001 |
FBuildingCostTarget_Name |
Wood |
FBuildingCostTarget_PrimaryAssetId |
Item:DA_Wood |
FBuildingCostTarget_SoftObject |
物品数据资产 |
DisplayName 和 Icon 只用于 UI 覆盖。未配置时,Evaluator 可以从目标数据或项目资源系统中获取显示信息。
FBuildingCostEntry¶
FBuildingCostEntry 表示由同一个 Evaluator 处理的一组成本目标。
USTRUCT(BlueprintType)
struct FBuildingCostEntry
{
GENERATED_BODY()
UPROPERTY(
EditAnywhere,
BlueprintReadOnly,
Category = "Building|Cost"
)
bool bEnabled = true;
UPROPERTY(
EditAnywhere,
BlueprintReadOnly,
Category = "Building|Cost"
)
FGameplayTag CostTypeTag;
UPROPERTY(
EditAnywhere,
BlueprintReadOnly,
Category = "Building|Cost"
)
TSubclassOf<UBuildingCostEvaluator> EvaluatorClass;
UPROPERTY(
EditAnywhere,
BlueprintReadOnly,
Category = "Building|Cost"
)
TArray<FBuildingCostTargetAmount> Costs;
};
| 字段 | 数据类型 | 默认值 | 说明 |
|---|---|---|---|
bEnabled |
bool |
true |
是否启用当前成本条目。 |
CostTypeTag |
FGameplayTag |
空 | 当前条目的成本类型。 |
EvaluatorClass |
TSubclassOf<UBuildingCostEvaluator> |
空 | 可选的 Evaluator 覆盖。 |
Costs |
TArray<FBuildingCostTargetAmount> |
空 | 当前 Evaluator 处理的目标列表。 |
CostTypeTag¶
CostTypeTag 用于标识成本类型,例如:
当 EvaluatorClass 未配置时,系统会根据 CostTypeTag 从项目设置中的 Default Evaluators 查找 Evaluator。
默认 Evaluator 使用 Gameplay Tag 精确匹配,不会自动匹配父标签或子标签。
EvaluatorClass¶
| 配置状态 | 使用的 Evaluator |
|---|---|
| 已配置 | 使用当前 Entry 指定的 EvaluatorClass。 |
| 未配置 | 根据 CostTypeTag 查找项目默认 Evaluator。 |
Costs¶
一个 Entry 可以包含多个由同一 Evaluator 处理的目标。
例如:
| 目标 | 数量 |
|---|---|
Resource.Wood |
10 |
Resource.Stone |
5 |
FBuildingCostContext¶
FBuildingCostContext 提供成本检查和资源消耗所需的运行时上下文。
Evaluator 应从 Context 中获取需要的对象,不建议长期保存这些引用。
USTRUCT(BlueprintType)
struct FBuildingCostContext
{
GENERATED_BODY()
UPROPERTY(BlueprintReadOnly, Category = "Building|Cost")
TObjectPtr<UObject> WorldContextObject = nullptr;
UPROPERTY(BlueprintReadOnly, Category = "Building|Cost")
TObjectPtr<AController> Controller = nullptr;
UPROPERTY(BlueprintReadOnly, Category = "Building|Cost")
TObjectPtr<UBuildingBuildComponent>
BuildingBuildComponent = nullptr;
UPROPERTY(BlueprintReadOnly, Category = "Building|Cost")
TObjectPtr<const UBuildingDataAsset>
BuildingData = nullptr;
UPROPERTY(BlueprintReadOnly, Category = "Building|Cost")
FTransform BuildTransform = FTransform::Identity;
};
| 字段 | 数据类型 | 默认值 | 说明 |
|---|---|---|---|
WorldContextObject |
UObject* |
nullptr |
用于获取当前 UWorld。 |
Controller |
AController* |
nullptr |
当前建筑操作的 Controller。 |
BuildingBuildComponent |
UBuildingBuildComponent* |
nullptr |
发起当前建筑操作的组件。 |
BuildingData |
const UBuildingDataAsset* |
nullptr |
当前建筑数据资产。 |
BuildTransform |
FTransform |
Identity | 当前请求的建筑世界变换。 |
WorldContextObject¶
用于解析当前世界:
UWorld* World =
IsValid(Context.WorldContextObject)
? Context.WorldContextObject->GetWorld()
: nullptr;
Controller¶
表示当前建筑操作的发起者。
Evaluator 可以通过它获取:
- Pawn
- Player State
- Inventory Component
- Currency Component
- 项目权限数据
该字段类型为 AController*,也可以接收 AI Controller。
BuildingBuildComponent¶
表示发起当前操作的建筑组件。
项目可以通过它获取:
- 组件 Owner
- Pawn
- 背包或资源组件
- 阵营或聚落数据
- 项目自定义成本来源
BuildingData¶
表示当前正在评估的建筑配置。
Evaluator 可以读取建筑类型、Gameplay Tags、Cost Set 和项目自定义配置。
该对象为只读,不应在成本检查过程中修改。
BuildTransform¶
表示当前建筑请求的世界变换。
可以用于实现与位置有关的成本或要求,例如:
- 根据区域计算成本
- 根据建筑高度增加费用
- 检查领地或位置权限
- 根据距离计算消耗
普通资源成本可以忽略该字段。
有效性检查¶
Evaluator 不应假设 Context 中的所有对象始终有效。
if (!IsValid(Context.Controller))
{
return FBuildingCostResult::Failure(
NSLOCTEXT(
"BuildingCost",
"InvalidController",
"Unable to resolve the building owner."
)
);
}
具体需要检查哪些字段,由 Evaluator 的实现决定。
FBuildingCostResult¶
FBuildingCostResult 表示成本检查或消耗结果。
USTRUCT(BlueprintType)
struct FBuildingCostResult
{
GENERATED_BODY()
UPROPERTY(BlueprintReadOnly, Category = "Building|Cost")
bool bSuccess = true;
UPROPERTY(BlueprintReadOnly, Category = "Building|Cost")
FText FailReason;
};
| 字段 | 数据类型 | 默认值 | 说明 |
|---|---|---|---|
bSuccess |
bool |
true |
操作是否成功。 |
FailReason |
FText |
空 | 操作失败时的原因。 |
Success¶
创建成功结果。
Failure¶
创建失败结果。
| 类型 | 名称 | 数据类型 | 说明 |
|---|---|---|---|
| Param | Reason |
const FText& |
失败原因。 |
| Return | Result |
FBuildingCostResult |
失败结果。 |
这些辅助函数主要供 C++ 使用。
FBuildingCostLine¶
FBuildingCostLine 表示建造 UI 中的一行资源、货币或物品成本。
USTRUCT(BlueprintType)
struct FBuildingCostLine
{
GENERATED_BODY()
UPROPERTY(BlueprintReadWrite, Category = "Building|UI")
FText DisplayName;
UPROPERTY(BlueprintReadWrite, Category = "Building|UI")
TObjectPtr<UTexture2D> Icon = nullptr;
UPROPERTY(BlueprintReadWrite, Category = "Building|UI")
int32 RequiredAmount = 0;
UPROPERTY(BlueprintReadWrite, Category = "Building|UI")
int32 OwnedAmount = 0;
UPROPERTY(BlueprintReadWrite, Category = "Building|UI")
bool bEnough = true;
UPROPERTY(BlueprintReadWrite, Category = "Building|UI")
FGameplayTag CostTypeTag;
};
| 字段 | 数据类型 | 默认值 | 说明 |
|---|---|---|---|
DisplayName |
FText |
空 | 成本名称。 |
Icon |
UTexture2D* |
nullptr |
成本图标。 |
RequiredAmount |
int32 |
0 |
所需数量。 |
OwnedAmount |
int32 |
0 |
当前拥有数量。 |
bEnough |
bool |
true |
当前数量是否足够。 |
CostTypeTag |
FGameplayTag |
空 | 当前成本类型。 |
FBuildingRequirementLine¶
FBuildingRequirementLine 表示一项非资源类建造要求。
常见用途包括:
- 玩家等级
- 科技解锁
- 建筑权限
- 声望要求
- 项目自定义限制
USTRUCT(BlueprintType)
struct FBuildingRequirementLine
{
GENERATED_BODY()
UPROPERTY(BlueprintReadWrite, Category = "Building|UI")
FText DisplayName;
UPROPERTY(BlueprintReadWrite, Category = "Building|UI")
FText CurrentValueText;
UPROPERTY(BlueprintReadWrite, Category = "Building|UI")
FText RequiredValueText;
UPROPERTY(BlueprintReadWrite, Category = "Building|UI")
bool bPassed = true;
UPROPERTY(BlueprintReadWrite, Category = "Building|UI")
FText FailReason;
};
| 字段 | 数据类型 | 默认值 | 说明 |
|---|---|---|---|
DisplayName |
FText |
空 | 要求名称。 |
CurrentValueText |
FText |
空 | 当前状态或数值。 |
RequiredValueText |
FText |
空 | 需要满足的状态或数值。 |
bPassed |
bool |
true |
当前要求是否通过。 |
FailReason |
FText |
空 | 未通过时的原因。 |
FBuildingBuildCheckResult¶
FBuildingBuildCheckResult 是所有成本和要求的 UI 聚合结果。
USTRUCT(BlueprintType)
struct FBuildingBuildCheckResult
{
GENERATED_BODY()
UPROPERTY(BlueprintReadWrite, Category = "Building|UI")
bool bCanBuild = true;
UPROPERTY(BlueprintReadWrite, Category = "Building|UI")
TArray<FBuildingCostLine> CostLines;
UPROPERTY(BlueprintReadWrite, Category = "Building|UI")
TArray<FBuildingRequirementLine> RequirementLines;
UPROPERTY(BlueprintReadWrite, Category = "Building|UI")
FText FirstFailReason;
};
| 字段 | 数据类型 | 默认值 | 说明 |
|---|---|---|---|
bCanBuild |
bool |
true |
所有成本和要求是否通过。 |
CostLines |
TArray<FBuildingCostLine> |
空 | 成本 UI 数据。 |
RequirementLines |
TArray<FBuildingRequirementLine> |
空 | 非资源要求 UI 数据。 |
FirstFailReason |
FText |
空 | 第一个失败原因。 |
该结果可以由以下接口生成:
或:
UBuildingCostEvaluator¶
UBuildingCostEvaluator 是成本处理器的基础类。
项目可以通过蓝图或 C++ 继承该类,对接自己的背包、货币或资源系统。
| 接口 | 说明 |
|---|---|
CanAfford |
检查当前成本是否能够支付。 |
Consume |
消耗当前成本。 |
EvaluateForUI |
生成 UI 使用的成本和要求信息。 |
CanAfford¶
UFUNCTION(
BlueprintNativeEvent,
BlueprintCallable,
Category = "Building|Cost"
)
FBuildingCostResult CanAfford(
const FBuildingCostContext& Context,
const FBuildingCostEntry& Entry
) const;
该接口只执行检查,不应修改资源状态。
Consume¶
UFUNCTION(
BlueprintNativeEvent,
BlueprintCallable,
Category = "Building|Cost"
)
FBuildingCostResult Consume(
const FBuildingCostContext& Context,
const FBuildingCostEntry& Entry
) const;
该接口负责实际消耗资源。
实现时应在修改资源前再次检查可用数量,因为运行时数据可能已经发生变化。
EvaluateForUI¶
UFUNCTION(
BlueprintNativeEvent,
BlueprintCallable,
Category = "Building|Cost"
)
FBuildingBuildCheckResult EvaluateForUI(
const FBuildingCostContext& Context,
const FBuildingCostEntry& Entry
) const;
该接口用于生成 UI 数据,不应消耗或修改资源。
UBuildingCostSet¶
UBuildingCostSet 是建筑使用的成本配置资产。
UCLASS(BlueprintType)
class UBuildingCostSet : public UDataAsset
{
GENERATED_BODY()
public:
UPROPERTY(
EditAnywhere,
BlueprintReadOnly,
Category = "Building|Cost"
)
TArray<FBuildingCostEntry> CostEntries;
};
CostEntries¶
CostEntries 保存建筑需要检查和消耗的成本条目。
一个 Cost Set 可以同时包含多种成本:
CanAfford¶
检查所有启用的成本条目,但不消耗资源。
Consume¶
调用各个成本条目的 Evaluator 执行资源消耗。
EvaluateForUI¶
void EvaluateForUI(
const FBuildingCostContext& Context,
FBuildingBuildCheckResult& InOutResult
) const;
将各个成本条目的 UI 数据写入现有的检查结果。
UI 使用建议¶
| 数据 | 用途 |
|---|---|
bCanBuild |
控制确认按钮是否可用。 |
CostLines |
显示资源、货币或物品成本。 |
RequirementLines |
显示等级、权限等要求。 |
FirstFailReason |
显示简短失败提示。 |
bEnough |
标记单项成本是否满足。 |
bPassed |
标记单项要求是否通过。 |
类型用途¶
| 类型 | 主要用途 |
|---|---|
FBuildingCostTargetBase |
自定义成本目标基类。 |
FBuildingCostTargetAmount |
单个目标和数量。 |
FBuildingCostEntry |
同一 Evaluator 处理的一组成本。 |
FBuildingCostContext |
成本操作的运行时上下文。 |
FBuildingCostResult |
检查或消耗结果。 |
FBuildingCostLine |
UI 成本行。 |
FBuildingRequirementLine |
UI 要求行。 |
FBuildingBuildCheckResult |
完整 UI 评估结果。 |
UBuildingCostEvaluator |
项目自定义成本处理器。 |
UBuildingCostSet |
建筑成本配置资产。 |