【UE4C++-ActionRougelike-06】UMG血量条


【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,在画布面板中添加血条和血量数字

血量UI界面布局

2.2 绑定玩家实际血量与血量UI数字显示

对血量数字文本与实际血量进行绑定。

更新血量数字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

血量脉冲动画

2.6 最终演示效果

血量变换效果

文章作者: Woilin
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Woilin !
评论
  目录