UE5 TakeDamage OnTakeAnyDamage多播委托

在 Unreal Engine 中,DamageTaken 通常与角色或对象受到伤害的机制相关。处理伤害是游戏开发中常见的需求,例如角色受到攻击、敌人被击中、道具受到破坏等。为了实现这一机制,Unreal Engine 提供了几种处理伤害的方式,其中包括使用 TakeDamage 函数和 OnTakeAnyDamage 委托。

1. 处理伤害的基础机制

1.1 TakeDamage 函数

TakeDamageAActor 类中的一个虚函数,用于处理角色或对象受到伤害的逻辑。可以在继承 AActor 的类中重写这个函数,以自定义处理伤害的行为。

// AMyCharacter.h class AMyCharacter : public ACharacter { GENERATED_BODY() public: // 重写 TakeDamage 函数 virtual float TakeDamage(float DamageAmount, FDamageEvent const& DamageEvent, AController* EventInstigator, AActor* DamageCauser) override; }; // AMyCharacter.cpp float AMyCharacter::TakeDamage(float DamageAmount, FDamageEvent const& DamageEvent, AController* EventInstigator, AActor* DamageCauser) { // 调用基类的 TakeDamage 函数,确保默认的伤害处理逻辑被执行 float ActualDamage = Super::TakeDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser); // 实现自定义的伤害处理逻辑 Health -= ActualDamage; if (Health <= 0.0f) { // 角色死亡逻辑 Die(); } return ActualDamage; }

TakeDamage 函数参数:
  • DamageAmount:伤害值,表示本次攻击的伤害量。
  • DamageEvent:伤害事件结构体,包含了伤害类型、伤害来源等信息。
  • EventInstigator:引发伤害的控制器(通常是玩家或 AI 控制器)。
  • DamageCauser:造成伤害的对象(如子弹、爆炸物)。

1.2 OnTakeAnyDamage 委托

OnTakeAnyDamageAActor 类中的一个多播委托,当 Actor 受到任何类型的伤害时,都会触发这个委托。可以使用 OnTakeAnyDamage.AddDynamic 在运行时将函数绑定到这个委托上。

// 在构造函数或 BeginPlay 中绑定委托 AMyCharacter::AMyCharacter() { OnTakeAnyDamage.AddDynamic(this, &AMyCharacter::HandleDamage); } void AMyCharacter::BeginPlay() { Super::BeginPlay(); // 绑定委托 OnTakeAnyDamage.AddDynamic(this, &AMyCharacter::HandleDamage); } // 定义处理伤害的函数 void AMyCharacter::HandleDamage(AActor* DamagedActor, float Damage, const UDamageType* DamageType, AController* InstigatedBy, AActor* DamageCauser) { // 自定义伤害处理逻辑 UE_LOG(LogTemp, Warning, TEXT("Actor %s took %f damage"), *DamagedActor->GetName(), Damage); Health -= Damage; if (Health <= 0.0f) { Die(); } }

OnTakeAnyDamage 委托参数:
  • DamagedActor:受到伤害的对象。
  • Damage:伤害值。
  • DamageType:伤害类型,通常继承自 UDamageType 类。
  • InstigatedBy:引发伤害的控制器(如玩家控制器)。
  • DamageCauser:造成伤害的对象(如子弹、爆炸物)。

2. 伤害类型的处理

Unreal Engine 提供了 UDamageType 类,用于定义不同类型的伤害,例如物理伤害、火焰伤害、毒药伤害等。你可以继承 UDamageType 创建自定义的伤害类型,并在 TakeDamageHandleDamage 函数中根据伤害类型做出不同的反应。

自定义伤害类型

// MyDamageType.h #pragma once #include "CoreMinimal.h" #include "GameFramework/DamageType.h" #include "MyDamageType.generated.h" UCLASS() class MYGAME_API UMyDamageType : public UDamageType { GENERATED_BODY() public: // 定义自定义的属性或方法 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Damage") bool bIsFireDamage = false; };

TakeDamage 函数中处理自定义伤害类型:

float AMyCharacter::TakeDamage(float DamageAmount, FDamageEvent const& DamageEvent, AController* EventInstigator, AActor* DamageCauser) { Super::TakeDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser); // 获取伤害类型 const UDamageType* DamageType = DamageEvent.DamageTypeClass->GetDefaultObject<UDamageType>(); if (DamageType) { // 判断是否是自定义的火焰伤害 if (DamageType->IsA<UMyDamageType>() && Cast<UMyDamageType>(DamageType)->bIsFireDamage) { // 执行火焰伤害的逻辑 UE_LOG(LogTemp, Warning, TEXT("Character took fire damage!")); } } return DamageAmount; }

3. 触发伤害

为了触发伤害,可以使用 UGameplayStatics::ApplyDamage 或其他类似的函数。这些函数会调用 TakeDamageOnTakeAnyDamage,并传递伤害信息。

使用 ApplyDamage

#include "Kismet/GameplayStatics.h" // ApplyDamage 函数触发伤害 UGameplayStatics::ApplyDamage(TargetActor, 10.0f, InstigatorController, DamageCauser, UDamageType::StaticClass());

ApplyDamage 函数参数:
  • TargetActor:受到伤害的对象。
  • 10.0f:伤害值。
  • InstigatorController:引发伤害的控制器。
  • DamageCauser:造成伤害的对象(如子弹、爆炸物)。
  • UDamageType::StaticClass():伤害类型,可以是自定义的 UDamageType 子类。

使用其他触发函数

  • ApplyPointDamage:应用点伤害,适合射线投射或子弹伤害。
  • ApplyRadialDamage:应用半径伤害,适合爆炸等影响范围内的伤害。
  • ApplyRadialDamageWithFalloff:应用带有衰减的半径伤害,适合爆炸中随着距离衰减的伤害。

// ApplyPointDamage UGameplayStatics::ApplyPointDamage(TargetActor, 15.0f, HitFromDirection, HitResult, InstigatorController, DamageCauser, UDamageType::StaticClass()); // ApplyRadialDamage UGameplayStatics::ApplyRadialDamage(GetWorld(), 20.0f, ExplosionLocation, DamageRadius, UDamageType::StaticClass(), IgnoreActors, DamageCauser, InstigatorController, true); // ApplyRadialDamageWithFalloff UGameplayStatics::ApplyRadialDamageWithFalloff(GetWorld(), 50.0f, 10.0f, ExplosionLocation, InnerRadius, OuterRadius, Falloff, UDamageType::StaticClass(), IgnoreActors, DamageCauser, InstigatorController, ECC_Visibility);

4. 蓝图中处理伤害

在蓝图中也可以处理伤害事件。你可以使用内置的事件节点,比如 Event AnyDamageEvent Point Damage,来处理受到的伤害。

使用 Event AnyDamage

  1. 在蓝图角色中,右键搜索 Event AnyDamage
  2. 添加该事件节点。
  3. 在事件节点中添加自定义逻辑,例如减少生命值、播放受击动画、更新 UI 等。

使用 Event Point DamageEvent Radial Damage

  1. Event Point Damage 处理点伤害事件,适合精确射击或刺击类攻击。
  2. Event Radial Damage 处理半径伤害事件,适合爆炸或范围攻击。

5. 总结

  • TakeDamageOnTakeAnyDamage 是 Unreal Engine 中处理伤害的主要机制。
  • UDamageType 可以用于定义不同类型的伤害,以便在处理时区分。
  • ApplyDamageApplyPointDamageApplyRadialDamage 等函数用于触发伤害事件。
  • 可以通过重写 TakeDamage 函数或绑定 OnTakeAnyDamage 委托来自定义伤害处理逻辑。
  • 蓝图中可以使用内置事件节点来处理伤害逻
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值