You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UE5 C++自定义碰撞事件无法触发,寻求排查解决方法

UE5 自定义碰撞事件无法触发的排查与修复

核心问题分析

  • 碰撞配置完全禁用:构造函数中调用了SetCollisionProfileName("NoCollision"),这个预设会彻底关闭组件的所有碰撞交互,包括Hit事件,这是导致事件无法触发的最关键原因。
  • 代码覆盖编辑器设置:构造函数里执行了SetNotifyRigidBodyCollision(false),直接覆盖了你在编辑器中开启的"Simulation Generates Hit Events"配置。
  • 根组件未正确初始化:创建CollisionBox后没有将其设为Actor的RootComponent,反而尝试附着到空的RootComponent上,导致碰撞组件的物理交互逻辑未正常激活。
  • Socket附着风险:BeginPlay中尝试将CollisionBox附着到"SphereCollisionSocket",如果该Socket不存在于RootComponent上,碰撞组件会处于错误位置,无法检测到有效碰撞。

修复方案

1. 修正碰撞基础配置

替换禁用碰撞的预设为合适类型,同时开启刚体碰撞通知,保证代码与编辑器设置一致。

2. 设置碰撞盒为根组件

将CollisionBox设为Actor的RootComponent,确保其作为物理交互的核心载体。

3. 验证Socket有效性(可选)

如果确实需要附着到Socket,先确认该Socket存在于对应组件上,否则移除不必要的附着代码。

4. 检查碰撞双方交互规则

确保与Drone碰撞的对象,其碰撞预设允许与Drone的碰撞配置产生Hit事件(比如对方的碰撞响应设置为"Block"或"Overlap")。

修改后的代码示例

头文件(无需调整)

#pragma once

#include "CoreMinimal.h"
#include "Components/BoxComponent.h"
#include "GameFramework/Actor.h"
#include "Kismet/GameplayStatics.h"
#include "StarWarsDrone.generated.h"

UCLASS()
class STARWARSTRAINING_UE5_API AStarWarsDrone : public AActor
{
    GENERATED_BODY()
    
    UPROPERTY(EditAnywhere)
        AActor* Enemy;
    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Collision, meta = (AllowPrivateAccess = "true"))
        class UBoxComponent* CollisionBox;


public: 
    // Sets default values for this actor's properties
    AStarWarsDrone();

    UFUNCTION()
    void OnAttackHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit);

protected:
    // Called when the game starts or when spawned
    virtual void BeginPlay() override;

public: 
    // Called every frame
    virtual void Tick(float DeltaTime) override;

};

CPP文件修改

#include "StarWarsDrone.h"

AStarWarsDrone::AStarWarsDrone()
{
    PrimaryActorTick.bCanEverTick = true;

    // 创建碰撞盒并设置为根组件
    CollisionBox = CreateDefaultSubobject<UBoxComponent>(TEXT("CollisionBox"));
    RootComponent = CollisionBox;

    // 使用支持碰撞交互的预设,可根据需求替换为自定义配置
    CollisionBox->SetCollisionProfileName("OverlapAllDynamic");
    // 开启刚体碰撞通知,与编辑器设置匹配
    CollisionBox->SetNotifyRigidBodyCollision(true);
    CollisionBox->SetHiddenInGame(false);
}

void AStarWarsDrone::BeginPlay()
{
    Super::BeginPlay();

    // 仅当确认Socket存在时保留以下代码,否则注释/删除
    //const FAttachmentTransformRules AttachmentRules(EAttachmentRule::SnapToTarget, EAttachmentRule::SnapToTarget, EAttachmentRule::KeepWorld, false);
    //CollisionBox->AttachToComponent(RootComponent, AttachmentRules, "SphereCollisionSocket");

    // 绑定碰撞事件
    CollisionBox->OnComponentHit.AddDynamic(this, &AStarWarsDrone::OnAttackHit);
}

void AStarWarsDrone::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);
}

void AStarWarsDrone::OnAttackHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
{
    UE_LOG(LogTemp, Warning, TEXT("OUCH"));
}

额外验证步骤

  • 开启编辑器的显示碰撞功能(快捷键Alt+C),确认CollisionBox的位置、大小符合预期。
  • 检查碰撞对象的碰撞组件是否开启了"Simulation Generates Hit Events"(如果是物理模拟对象)。
  • 测试时确保碰撞双方处于可交互状态(比如对方Actor未被设置为"隐藏碰撞")。

内容的提问来源于stack exchange,提问作者Paul Miller

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 18:45:42