NT-2.3|数据结构
大约 9 分钟
数据结构|结构体
数据结构|Datatable|表格
USTRUCT(BlueprintType)
struct FCharacterStruct : public FTableRowBase
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta=(DisplayName="Name"))
FString Name;
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta=(DisplayName="Icon", MakeStructureDefaultValue="None"))
TObjectPtr<UTexture2D> Icon;
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta=(DisplayName="SkeletalMesh", MakeStructureDefaultValue="None"))
TObjectPtr<USkeletalMesh> SkeletalMesh;
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta=(DisplayName="SkeletalAnim", MakeStructureDefaultValue="None"))
TObjectPtr<UAnimSequence> SkeletalAnim;
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta=(DisplayName="SkeletalAnimSpeed", MakeStructureDefaultValue="1.000000"))
float SkeletalAnimSpeed = 1.0;
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta=(DisplayName="id", MakeStructureDefaultValue="0"))
int32 id = 0;
};
数据结构|Json-API
注
API(Application Programming Interface)是一组定义软件组件之间交互的规范。简而言之,API定义了不同软件之间如何通信、相互调用功能的方式。
数据结构|Json
注
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,它以易于阅读和编写的文本形式表示数据。
{
"key1": "value1",
"key2": 123,
"key3": true,
"key4": ["item1", "item2"],
"key5": {
"nestedKey": "nestedValue"
},
"key6": null
}
数据结构|数据库
数据结构|数据资产
抛砖引玉
Table+子系统+资产实现配表驱动
使用子系统UInventorySubsystem
- 引入专门的物品子系统,例如
UInventorySubsystem
,用于处理物品的管理和交互。
- 引入专门的物品子系统,例如
暴露切换网络接口 (ENUM)
- 使用枚举类型(ENUM)定义网络切换的接口,确保系统在本地测试和网络测试时有不同的行为。
- 示例:
InventorySubsystem->SetNetworkMode(NetworkMode);
本地部分使用流程
- 在适当时机注册
InventoryHUDLayout
,可参考Lyra的UIExtension。 - 示例:
InventorySubsystem->RegisteInventoryHUDLayout(InventoryHUDLayout);
- 在适当时机注册
在适当的位置注册总物品表 TotalItemTable 到物品子系统
- 示例:
InventorySubsystem->RegisterTotalTable(TotalItemTable);
- 例如:
- 行名1(武器.近身.匕首), UDataTable* SubTable
- 行名2(武器.近身.长剑), UDataTable* SubTable
- 行名3(道具.血包), UDataTable* SubTable
- 示例:
准备Spawn的物体Actor中配置GameTag和Index
- 示例:
ItemActor->ConfigureItem(GameTag, Index);
- 示例:
Actor中Over事件调用子系统查表
- 获取子表格的引用,例如:
UDataTable* SubTable = InventorySubsystem->GetSubTableFromTotalTable(GameTag);
- 通过GameTag直接定位到总表格的对应行,获取子表格的引用。
- 获取子表格的引用,例如:
子系统根据Fragments实例化内容
- 根据Fragments数组中的
UInventoryItemFragment
子类实例,配置对应的内容。 - 例如:基础
TextureFrag
(Icon)、AS
(属性)、MeshComponent
(网格体)、AddWidget
(比如根据HUD.Slot
、UIClass
配置要显示的 UI)等
- 根据Fragments数组中的
子系统暴露交互键注册函数
- 子系统应当暴露接口,用于注册交互键,可能涉及 UI 的绑定以及信息更新。
- 示例:子系统接口
RegisterInteractionKey
。
职责思考
注册
注册|注册时机
/**注册装备数据表。**/
UFUNCTION(BlueprintCallable, Category="PlayerDataSubsystem|InventoryData")
void RegisterInventoryTable(UDataTable* Table);
/**获取装备表格。**/
UFUNCTION(BlueprintPure, Category="PlayerDataSubsystem|InventoryData")
UDataTable* GetInventoryTable() const;
//装备表格
UPROPERTY(BlueprintReadWrite, EditAnywhere, meta=(AllowPrivateAccess))
UDataTable* InventoryTable;
注册|动态更新
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FDataUpDateDelegate)
UPROPERTY(BlueprintAssignable, Category = "DataSubsystem")
FDataUpDateDelegate DataInitDelegate;
注册|标签关联
进一步思考
void RegisterInventoryTable(UDataTable* Table);
void RegisterPlayerDataTable(UDataTable* Table);
......
//增加表格
UFUNCTION(BlueprintCallable, Category="DataSubsystem")
void InsertDataTableByTag(UDataTable* Table,FGameplayTag Tag);
//删除表格
UFUNCTION(BlueprintCallable, Category="DataSubsystem")
void DeleteDataTableByTag(FGameplayTag Tag);
//查找数据
UFUNCTION(BlueprintCallable, Category="DataSubsystem")
UDataTable* SelectDataTableByTag(FGameplayTag Tag,bool & IsFind );
TMap<FGameplayTag, UDataTable*> DataTableMap;
注意现在的所有讨论都是一种思维演变的讨论,不应该作为最终版本的参考。
转换
数据转换|数据源
数据转换|HTTP请求
数据转换|格式转换
//jsontostring
bool FJsonObjectWrapper::JsonObjectToString(FString& Str) const
{
TSharedRef<TJsonWriter<TCHAR, TCondensedJsonPrintPolicy<TCHAR>>> JsonWriter = TJsonWriterFactory<TCHAR, TCondensedJsonPrintPolicy<TCHAR>>::Create(&Str, 0);
return FJsonSerializer::Serialize(JsonObject.ToSharedRef(), JsonWriter, true);
}
//jsonfromstring
bool FJsonObjectWrapper::JsonObjectFromString(const FString& Str)
{
TSharedRef<TJsonReader<>> JsonReader = TJsonReaderFactory<>::Create(Str);
return FJsonSerializer::Deserialize(JsonReader, JsonObject);
}
数据转换|RuntimeDataTable
void UPlayerDataSubsystem::SetHeroesSkinIDMap(TMap<FName, int32>& InPlayerSelectedHero)
{
UExorcistSettingsLocal* Settings = UExorcistSettingsLocal::Get();
Settings->SetHeroesSkinIDMap(InPlayerSelectedHero);
Settings->SaveSettings();
}
权限
修改权限
权限级别 | 可修改数据 | 可修改贴图 | 可修改皮肤ID | 修改方式 |
---|---|---|---|---|
0 | 是 | 是 | 是 | 直接 |
1 | 是 | 否 | 是 | 直接 |
2 | 否 | 否 | 否 | 请求 |
独立模式
- 用户拥有权限级别 0 - 2,因为客户端和服务器都由用户自己控制。权限 0 更像是开发者模式,开启状态。
监听服务器模式
- 服务器端拥有权限级别 0 和 1,因为对于其他客户端来说,服务器是权威版本。其他客户端只有权限级别 2。
专用服务器模式
- 所有客户端都只有权限级别 2,因为服务器是专用服务器,不允许其他客户端修改数据。