一.3Dwidget
1.创建C++ Userwidget的 MyHealthWidget,声明当前血量和最大血量
cpp
UCLASS()
class PRACTICEC_API UMyHealthWidget : public UUserWidget
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere,BlueprintReadWrite,Category = "MyWidget")
float CurrentHealth = 100.0f;
UPROPERTY(EditAnywhere,BlueprintReadWrite,Category = "MyWidget")
float MaxHealth = 100.0f; //可以给默认值
};
2.创建UMG的蓝图,ClassSetting里 继承 MyHealthWidget.
二.渲染到屏幕
在Charactor的构造函数中,构建子组件。并且静态加载UMG类。设置位置,屏幕,大小等。
cpp
UWidgetComponent* MyWidgetHealth;
cpp
MyWidgetHealth = CreateDefaultSubobject<UWidgetComponent>(TEXT("MyWidgetComponent"));
MyWidgetHealth->SetupAttachment(RootComponent);
static ConstructorHelpers::FClassFinder<UUserWidget>WidgetClass(TEXT("/Script/UMGEditor.WidgetBlueprint'/Game/UMG_Health.UMG_Health_C'")); //静态加载
MyWidgetHealth->SetWidgetClass(WidgetClass.Class);
MyWidgetHealth->SetRelativeLocation(FVector(0,0,100));
MyWidgetHealth->SetWidgetSpace(EWidgetSpace::Screen); // 输出到屏幕
MyWidgetHealth->SetDrawSize(FVector2D(400,20));
三.碰撞伤害
1.在Actor 添加头文件 和 碰撞函数
cpp
#include "Kismet/GameplayStatics.h" //Aplaydamage 函数库里的头文件
#include "MyCharacter.h" //后面用于转化
cpp
UFUNCTION()
void BeginOverlapFunction(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
UFUNCTION()
void EndOverlapFunction( UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex); //四个参数
// FComponentEndOverlapSignature, UPrimitiveComponent, OnComponentEndOverlap, UPrimitiveComponent*, OverlappedComponent, AActor*, OtherActor, UPrimitiveComponent*, OtherComp, int32, OtherBodyIndex
2.在CPP里实现 ,如果人物刚碰撞 ApplyDamage();
cpp
void AMyActor::BeginOverlapFunction(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
AMyCharacter* MyCharacter = Cast<AMyCharacter>(OtherActor); //转换
if (MyCharacter)
{
UGameplayStatics::ApplyDamage(MyCharacter,5.0f,nullptr,this,UDamageType::StaticClass()); //应用伤害
}
GEngine->AddOnScreenDebugMessage(-1,5.0f,FColor::Red,TEXT("BeginOverLapEvent is Success"));
MyParticle->Activate(); //激活
}
四.人物收到伤害 血条响应
重写内部受伤函数
cpp
virtual float TakeDamage(float DamageAmount,FDamageEvent const &DamageEvent,class AController*EventInstigator,AActor* DamagerCausser)override; //重写系统内部的TakeDamage
cpp
float AMyCharacter::TakeDamage(float DamageAmount, FDamageEvent const& DamageEvent, AController* EventInstigator, AActor* DamagerCausser)
{
UMyHealthWidget* MyWidget = Cast<UMyHealthWidget>(MyWidgetHealth->GetUserWidgetObject());
if (MyWidget)
{
if (MyWidget->CurrentHealth > 0)
{
MyWidget->CurrentHealth -= 5.f;
}
else
{
return 0.f;
}
}
return 0.0f;
}
获得指针UserWidget 转换为 UMyHealthWidget,做相应的逻辑操作。