【UE4C++-ActionRougelike-06】UMG血量条
UMG全称虚幻示意图形界面设计器(Unreal Motion Graphics UI Designer)
1、创建血量属性
为角色创建血量属性最直接的做法即在角色MyCharacter中定义一个Health变量。但当项目越来越大时,角色的属性可能会随之增加,导致MyCharacter中的内容过多而难以维护。
因此类似于先前所设计的玩家交互组件时,使用UE中的ActorComponent类,创建一个属性组件类被MyCharacter拥有。用于实现角色的各种属性。
1.1 创建角色属性组件类
以ActorComponent为父类创建C++类MyAttributeComponent表示角色属性组件类
在MyAttributeComponent.h声明血量变量和改变血量方法
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class ACTIONROGUELIKE_API UMyAttributeComponent : public UActorComponent
{
GENERATED_BODY()
public:
// Sets default values for this component's properties
UMyAttributeComponent();
protected:
//血量
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Attributes")
float Health;
public:
//对血量的改变
UFUNCTION(BlueprintCallable, Category = "Attributes")
bool ApplyHealthChange(float Delta);
};
在MyAttributeComponent.cpp中初始化Health变量和ApplyHealthChange方法的实现
UMyAttributeComponent::UMyAttributeComponent()
{
Health = 100;
}
bool UMyAttributeComponent::ApplyHealthChange(float Delta)
{
Health += Delta;
return true;
}
1.2 添加属性组件到MyCharacter类
在MyCharacter.h中添加属性组件类AttributeComp
class ACTIONROGUELIKE_API AMyCharacter : public ACharacter
{
protected:
//属性组件
UPROPERTY(VisibleAnywhere,BlueprintReadOnly, Category = "Components")
UMyAttributeComponent* AttributeComp;
}
在MyCharacter.cpp构造函数中初始化组件
AMyCharacter::AMyCharacter()
{
//属性组件
AttributeComp = CreateDefaultSubobject<UMyAttributeComponent>("AttributeComp");
}
1.3 魔法攻击类附加伤害计算
为魔法攻击类MyMagicProjectile.cpp中添加伤害计算,在球体组件中绑定OnComponentBeginOverlap事件用于魔法攻击效果与角色重叠时触发伤害计算。
AMyMagicProjectile::AMyMagicProjectile()
{
//魔法攻击与Actor重叠时触发伤害计算
SphereComp->OnComponentBeginOverlap.AddDynamic(this, &AMyMagicProjectile::OnActorOverlap);
}
void AMyMagicProjectile::OnActorOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
if (OtherActor)
{
//获得AttributeComp
UMyAttributeComponent* AttributeComp = Cast<UMyAttributeComponent>(OtherActor->GetComponentByClass(UMyAttributeComponent::StaticClass()));
//再次判空,重叠的可能是没有属性组件的物体
if (AttributeComp) {
AttributeComp->ApplyHealthChange(-20.0f);
Destroy();
}
}
}
1.4 修改魔法攻击类碰撞预设
1.5 血量修改测试
在PlayerCharacter_BP蓝图中每个Tick输出当前血量到屏幕上
最终测试效果如下:
2、血量UI
2.1 创建血量widget类
创建血量widget类PlayerHealth_Widget,在画布面板中添加血条和血量数字
2.2 绑定玩家实际血量与血量UI数字显示
对血量数字文本与实际血量进行绑定。
2.3 多播委托
绑定函数更新血量会每帧刷新造成资源浪费,使用多播委托自定义血量更新事件来实现,只需调用一次Broadcast函数就可使所有绑定的对象触发相应功能。
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(DelegateName, Param1Type, Param1Name)
/*
参数:委托名、参数类型、参数名
*/
在MyAttributeComponent.h中声明多播委托OnHealthChange
// 发起者,控件拥有者,改变后的血量,变化值
DECLARE_DYNAMIC_MULTICAST_DELEGATE_FourParams(FOnHealthChange, AActor*, InstigatorActor, UMyAttributeComponent*, OwningComp, float, NewHealth, float, Delta);
class ACTIONROGUELIKE_API UMyAttributeComponent : public UActorComponent
{
//多播委托FOnHealthChange
UPROPERTY(BlueprintAssignable)
FOnHealthChange OnHealthChange;
}
在MyAttComponent.cpp中当血量变化时OnHealthChange进行广播
bool UMyAttributeComponent::ApplyHealthChange(float Delta)
{
Health += Delta;
//委托进行广播
OnHealthChange.Broadcast(nullptr,this, Health,Delta);
return true;
}
2.4 更新血量条UI
通过事件构造将玩家Pawn的AttributeComp绑定到OnHealthChanged事件上。每次OnHealthChanged事件触发时计算当前血量与玩家默认血量的百分比,并设置给进度条。
2.5 优化血量改变动画效果
新建动画PlusHealthAnimal,在0.00和0.75设置血量文字缩放1.0,中间处设置缩放1.2