GetInstigatorController
是 Unreal Engine 中的一个方法,用于获取触发(Instigate)某个事件或动作的控制器(AController
)。通常在处理伤害、交互等涉及到角色控制器的逻辑时使用,它可以帮助你确定是谁(玩家或 AI)引发了某个事件或动作。
1. GetInstigatorController
的基本概念
GetInstigatorController
通常用于获取导致某个行为或事件的 AController
实例,这个控制器可以是玩家控制器(APlayerController
)或 AI 控制器(AAIController
)。
主要用途:
- 伤害系统:在伤害事件中,用于获取是谁引发了伤害(例如玩家射击、AI 攻击)。
- 交互系统:在触发某个交互事件时,用于获取哪个角色(玩家或 AI)触发了事件。
- 技能系统:在技能施放时,用于获取哪个角色(玩家或 AI)施放了技能。
2. GetInstigatorController
的使用
GetInstigatorController
通常在与 ApplyDamage
、ApplyPointDamage
或 ApplyRadialDamage
等函数一起使用时,获取引发伤害的控制器。它也可以在其他需要判断事件来源的场景中使用。
示例:获取伤害的引发者
#include "GameFramework/Controller.h" #include "GameFramework/Actor.h" // 假设这个函数被调用时会处理一个伤害事件 void AMyCharacter::HandleDamage(float DamageAmount) { AController* InstigatorController = GetInstigatorController(); if (InstigatorController) { // 确定是由玩家还是 AI 引发的伤害 if (InstigatorController->IsPlayerController()) { UE_LOG(LogTemp, Warning, TEXT("Damage instigated by player.")); } else { UE_LOG(LogTemp, Warning, TEXT("Damage instigated by AI.")); } } }
示例:在 TakeDamage
函数中使用
当一个 Actor
收到伤害时,可以在 TakeDamage
函数中调用 GetInstigatorController
获取引发伤害的控制器。
float AMyCharacter::TakeDamage(float DamageAmount, FDamageEvent const& DamageEvent, AController* EventInstigator, AActor* DamageCauser) { // 调用基类的 TakeDamage 函数 float ActualDamage = Super::TakeDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser); // 获取引发伤害的控制器 AController* InstigatorController = GetInstigatorController(); if (InstigatorController) { // 判断是否是玩家控制器 if (InstigatorController->IsPlayerController()) { UE_LOG(LogTemp, Warning, TEXT("Player caused damage.")); } } return ActualDamage; }
示例:在 ApplyDamage
中传递控制器
在使用 ApplyDamage
函数时,可以传递一个控制器作为引发伤害的控制者(Instigator),然后在 TakeDamage
或委托中通过 GetInstigatorController
获取它。
// 在某个地方(如玩家武器)应用伤害 UGameplayStatics::ApplyDamage(TargetActor, 25.0f, PlayerController, DamageCauser, UDamageType::StaticClass());
在目标 Actor
的 TakeDamage
函数中:
float AMyCharacter::TakeDamage(float DamageAmount, FDamageEvent const& DamageEvent, AController* EventInstigator, AActor* DamageCauser) { // EventInstigator 就是应用伤害时传递的控制器 if (EventInstigator) { UE_LOG(LogTemp, Warning, TEXT("Damage caused by: %s"), *EventInstigator->GetName()); } return Super::TakeDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser); }
3. Instigator
和 DamageCauser
的区别
在 Unreal Engine 的伤害系统中,经常会遇到 Instigator
和 DamageCauser
这两个概念,它们的作用有所不同:
Instigator
(引发者)
Instigator
通常是指引发某个行为或事件的角色控制器(AController
),例如:- 玩家射击,玩家控制器是
Instigator
。 - AI 施放技能,AI 控制器是
Instigator
。
- 玩家射击,玩家控制器是
Instigator
由AActor
类的Instigator
成员变量表示。
DamageCauser
(伤害来源)
DamageCauser
是指直接造成伤害的对象,例如:- 子弹击中敌人,子弹是
DamageCauser
。 - 爆炸伤害中的爆炸物(如手榴弹)是
DamageCauser
。
- 子弹击中敌人,子弹是
DamageCauser
由ApplyDamage
系列函数中的DamageCauser
参数指定。
关系和场景示例
- 玩家控制角色用枪射击敌人:
Instigator
:玩家控制器(PlayerController
)。DamageCauser
:子弹(Bullet
)。
- AI 控制的敌人发射火球攻击玩家:
Instigator
:AI 控制器(AIController
)。DamageCauser
:火球(Fireball
)。
4. GetInstigator
与 GetInstigatorController
的区别
-
GetInstigator()
:- 返回的是引发行为的
Pawn
或Character
(通常是APawn
类型),即具体的角色或实体对象。
- 返回的是引发行为的
-
GetInstigatorController()
:- 返回的是引发行为的
Controller
(通常是AController
类型),即控制角色的控制器对象。
- 返回的是引发行为的
通常情况下,你可以通过 GetInstigator()
获取具体的角色对象,而通过 GetInstigatorController()
获取控制该角色的控制器。
使用场景示例
GetInstigator()
:用来获取造成行为的具体角色实体,例如获取角色的位置信息、名称等。
APawn* InstigatingPawn = GetInstigator(); if (InstigatingPawn) { UE_LOG(LogTemp, Warning, TEXT("Instigator: %s"), *InstigatingPawn->GetName()); }
GetInstigatorController()
:用来判断引发行为的控制器是谁,例如判断是玩家控制器还是 AI 控制器。
AController* InstigatorController = GetInstigatorController(); if (InstigatorController && InstigatorController->IsPlayerController()) { UE_LOG(LogTemp, Warning, TEXT("Instigator is a player.")); }
5. 典型应用场景
5.1 伤害系统
在伤害系统中,GetInstigatorController
用于判断是谁(哪一个控制器)引发了伤害,例如玩家攻击敌人,或者 AI 攻击玩家。
5.2 交互系统
在交互系统中,可以使用 GetInstigatorController
来判断是哪一个玩家或 AI 与某个物体进行交互,从而做出相应的反应。
5.3 技能系统
在技能系统中,可以通过 GetInstigatorController
确定是谁施放了技能,以便在技能影响时做出正确的反应。
6. 总结
GetInstigatorController
用于获取引发某个事件或行为的控制器。- 在伤害、交互、技能等系统中经常使用,用于确定引发行为的角色或控制器。
- 区分
Instigator
和DamageCauser
,以及GetInstigator()
和GetInstigatorController()
的不同用途。 - 结合
ApplyDamage
系列函数,可以在TakeDamage
或OnTakeAnyDamage
等事件处理中获取引发事件的控制器信息。