UE4 C++实现碰撞重叠伤害时AddDynamic绑定事件报错如何解决?
问题根源
你当前的报错由两个核心错误导致:
- 委托绑定的类不匹配:
AddDynamic要求第一个参数传入的对象所属类,必须和第二个参数传入的成员函数所属类完全一致。你当前代码里第一个参数是this(即ABasicZombie实例),但成员函数是AMainCharacter的OnCollision,类型不匹配,因此直接报红。 - 回调函数缺少UE反射标记:UE的动态委托绑定依赖反射系统,所有被
AddDynamic绑定的回调函数必须添加UFUNCTION()宏修饰,否则反射系统无法识别该函数。
另外你疑惑的OnActorBeginOverlap找不到的问题,是因为该事件是AActor类的成员,只有Actor本身可以直接调用,UBoxComponent是组件类,仅提供OnComponentBeginOverlap事件。
修复方案
推荐选择第一种方案,逻辑内聚性更高,后续维护更方便。
方案1:重叠回调逻辑放在僵尸类(推荐)
- 在
BasicZombie.h中新增回调函数声明,添加UFUNCTION()标记:
// 在ABasicZombie类的public/protected块中添加如下代码 UFUNCTION() void OnOverlapWithPlayer(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
- 修改
BasicZombie.cpp构造函数中的绑定代码,替换原报错行:
// 删除原报错的绑定代码,替换为如下内容 BoxCollider->OnComponentBeginOverlap.AddDynamic(this, &ABasicZombie::OnOverlapWithPlayer);
- 在
BasicZombie.cpp中实现回调函数,处理伤害逻辑:
void ABasicZombie::OnOverlapWithPlayer(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) { // 校验重叠对象是否为玩家 AMainCharacter* Player = Cast<AMainCharacter>(OtherActor); if (Player) { // 可根据需求调整伤害数值、伤害事件参数 Player->TakeDamage(20.f, FDamageEvent(), GetInstigatorController(), this); } }
方案2:重叠回调逻辑放在玩家类
如果你的业务逻辑要求回调放在玩家侧,按如下步骤修改:
- 给
MainCharacter.h中的OnCollision函数添加UFUNCTION()标记:
// 修改原OnCollision声明为如下内容 UFUNCTION() void OnCollision(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComponent, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& Hit);
- 删除
BasicZombie.cpp构造函数中原报错的绑定代码,移到BeginPlay中执行:
void ABasicZombie::BeginPlay() { Super::BeginPlay(); AMainCharacter* Player = Cast<AMainCharacter>(GetWorld()->GetFirstPlayerController()->GetCharacter()); if (Player && BoxCollider) { BoxCollider->OnComponentBeginOverlap.AddDynamic(Player, &AMainCharacter::OnCollision); } }
额外注意点
你当前AMainCharacter构造函数中的playerScore = currentScore;逻辑写反,初始化时应该给currentScore赋值,建议修改为currentScore = 0;,避免后续出现分数异常问题。
内容的提问来源于stack exchange,提问作者George_H
相关产品推荐
相关产品推荐

