由于后期增加网络模块,许多数据肯定要通过协议初始化。所以这里属性管理通过c++实现。
首先需要有一个角色基类,这里叫CharactorBase。
然后需要有一个属性组件,然后在charactorBase里加载这个组件,这样以后在别的模块内调属性的时候,就可以通过调类似getCom的方法来取属性组件了,同时,为了以后可以方便管理属性和属性组,这里使用枚举来定义属性。
AttrActorComponent.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "AttrActorComponent.generated.h"
UENUM(BlueprintType)
enum class EnumAttrGroup :uint8 //设置uint8类型
{
Unit UMETA(DisplayName = "unit"), //想要显示中文 需要将编码格式设置为utf-8,DisPlayName表示显示的名称,在蓝图中可见
};
UENUM(BlueprintType)
enum class EnumAttrType :uint8 //设置uint8类型
{
HpMax UMETA(DisplayName = "hpMax"), //想要显示中文 需要将编码格式设置为utf-8,DisPlayName表示显示的名称,在蓝图中可见
};
//这种可以用结构体转换
USTRUCT(BlueprintType)
struct FAttrType
{
GENERATED_USTRUCT_BODY()
UPROPERTY(EditAnywhere, BlueprintReadOnly)
TMap<EnumAttrType, int64> AttrMap;
};
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class ACTOR_DEMO_API UAttrActorComponent : public UActorComponent
{
GENERATED_BODY()
public:
// Sets default values for this component's properties
UAttrActorComponent();
protected:
// Called when the game starts
virtual void BeginPlay() override;
public:
// Called every frame
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
void InitAttrGroupMap();
UFUNCTION(BlueprintCallable, Category = "AttrActor")
int GetAttr(EnumAttrGroup AttrGroup,EnumAttrType attrType);
UFUNCTION(BlueprintCallable, Category = "SetAttrActor")
void SetAttr(EnumAttrGroup AttrGroup, EnumAttrType attrType,int num);
UPROPERTY()
TMap<EnumAttrGroup, FAttrType> AttrGroupMap;
};
由于我目前没有发现ue4的tmap里如何嵌套另一层tmap,所以这里用一个USTRUCT来做转换。
AttrActorComponent.app
// Fill out your copyright notice in the Description page of Project Settings.
#include "Components/AttrActorComponent.h"
// Sets default values for this component's properties
UAttrActorComponent::UAttrActorComponent()
{
// 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 = false;
this->InitAttrGroupMap();
// ...
}
// Called when the game starts
void UAttrActorComponent::BeginPlay()
{
Super::BeginPlay();
// ...
}
// Called every frame
void UAttrActorComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
// ...
}
void UAttrActorComponent::InitAttrGroupMap() {
auto attrTypeMap = new FAttrType();
attrTypeMap->AttrMap.Add(EnumAttrType::HpMax, 1000);
AttrGroupMap.Add(EnumAttrGroup::Unit, *attrTypeMap);
}
int UAttrActorComponent::GetAttr(EnumAttrGroup AttrGroup, EnumAttrType attrType) {
if (AttrGroupMap.Contains(AttrGroup) == false) {
return 0;
}
FAttrType Group = AttrGroupMap[AttrGroup];
if (Group.AttrMap.Contains(attrType) == false) {
return 0;
}
return Group.AttrMap[attrType];
}
void UAttrActorComponent::SetAttr(EnumAttrGroup AttrGroup, EnumAttrType attrType, int num)
{
if (AttrGroupMap.Contains(AttrGroup) == false) {
auto attrTypeMap = new FAttrType();
attrTypeMap->AttrMap.Add(attrType, num);
AttrGroupMap.Add(AttrGroup, *attrTypeMap);
return;
}
FAttrType Group = AttrGroupMap[AttrGroup];
if (Group.AttrMap.Contains(attrType) == false) {
Group.AttrMap.Add(attrType, num);
return;
}
Group.AttrMap[attrType] = num;
}
创建一个ui文件
这里叫PlayerRoleAttrUi
这里简单做了一个这样的图
点击下面的面板,并绑定文本到方法函数
这里就可以直接通过组件里的方法来获取到对应的属性了。
通过按键事件,创建对应的空控件并绑定到视口。