【问题标题】:Collisions detection with OnComponentHit UE4 C++使用 OnComponentHit UE4 C++ 进行碰撞检测
【发布时间】:2019-09-17 08:11:56
【问题描述】:

我遇到了碰撞问题。我想做简单的弹丸。我制作了一个具有 Root、Sphere 和网格组件的 Actor。当这个演员击中目标对象时,什么也没有发生。 我尝试了很多方法,也有

void OnOverlapBegin(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);


void OnOverlapEnd(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);

函数,但没有任何结果..

这是我的自定义射弹的构造函数:

AProjectile_2::AProjectile_2()
{
    // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = true;

    Root = CreateDefaultSubobject<USceneComponent>(TEXT("Root"));
    RootComponent = Root;

    mesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("staticMesh"));
    static ConstructorHelpers::FObjectFinder<UStaticMesh>SphereMeshAsset(TEXT("/Game/StarterContent/Shapes/Shape_Sphere.Shape_Sphere"));
    if (SphereMeshAsset.Succeeded())
    {
        mesh->SetStaticMesh(SphereMeshAsset.Object);
        mesh->SetWorldScale3D(FVector(0.2f));
    }
    mesh->SetEnableGravity(true);
    mesh->SetSimulatePhysics(true);
    mesh->SetupAttachment(Root);

    Sphere = CreateDefaultSubobject<USphereComponent>(TEXT("SphereComponent"));
    Sphere->InitSphereRadius(5.f);
    Sphere->SetupAttachment(Root);

    Sphere->SetCollisionProfileName(TEXT("Target"));

    Sphere->OnComponentHit.AddDynamic(this, &AProjectile_2::OnHit);
    Sphere->SetupAttachment(RootComponent);

    InitialLifeSpan = 5.f;
}

这是一个检测函数

void AProjectile_2::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
{
    if ((OtherActor != NULL) && (OtherActor != this) && (OtherComp != NULL))
    {
        if (OtherActor && (OtherActor != this) && OtherComp && OtherActor->GetClass()->IsChildOf(ADestroypack::StaticClass()))
        {
            destroypack = (ADestroypack*)OtherActor;
            destroypack->decreasehp(50);
            destroypack->check_hp();
            destroypack->showhp();
        }
    }
}

我的网格在这里移动

void AProjectile_2::Initvel(FVector Velocity)
{
    mesh->AddForce(Velocity * 300);
}

这是我用人民币按钮拍摄的角色功能

void AHero::Attack_right()
{
    FVector Location = GetWorld()->GetFirstPlayerController()->GetPawn()->GetActorLocation();
    FRotator Rotation = GetWorld()->GetFirstPlayerController()->GetPawn()->GetActorRotation();

    GetActorEyesViewPoint(Location, Rotation);
    projectiles = (AProjectile_2*) GetWorld()->SpawnActor(AProjectile_2::StaticClass(), &Location, &Rotation);
    FVector LaunchDir;
    LaunchDir = GetActorForwardVector() * 5000.f;
    projectiles->Initvel(LaunchDir);
}

如果有人能说出我做错了什么,或者我的项目中缺少什么,我将不胜感激。

好的!我已经弄清楚了! :D 我在网格和球体中添加重力和物理时犯了一个错误。我已经从网格中删除了它,它现在可以工作了:)

AProjectile_2::AProjectile_2()
{
    // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = true;

    //Root = CreateDefaultSubobject<USceneComponent>(TEXT("Root"));
    //RootComponent = Root;

    Sphere = CreateDefaultSubobject<USphereComponent>(TEXT("SphereComponent"));
    Sphere->SetSimulatePhysics(true);
    Sphere->SetEnableGravity(true);
    Sphere->SetNotifyRigidBodyCollision(true);
    Sphere->InitSphereRadius(40.f);
    Sphere->BodyInstance.SetCollisionProfileName("BlockAllDynamic");
    Sphere->SetCollisionProfileName(TEXT("Target"));
    Sphere->OnComponentHit.AddDynamic(this, &AProjectile_2::OnHit);
    RootComponent = Sphere;

    mesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("staticMesh"));
    static ConstructorHelpers::FObjectFinder<UStaticMesh>SphereMeshAsset(TEXT("/Game/StarterContent/Shapes/Shape_Sphere.Shape_Sphere"));
    if (SphereMeshAsset.Succeeded())
    {
        mesh->SetStaticMesh(SphereMeshAsset.Object);
        mesh->AddRelativeLocation(FVector(0.f, 0.f, 0.f));
        mesh->SetWorldScale3D(FVector(0.2f));
    }
    /*mesh->SetEnableGravity(true);
    mesh->SetSimulatePhysics(true);
    mesh->SetGenerateOverlapEvents(true);*/
    mesh->SetupAttachment(RootComponent);

    InitialLifeSpan = 5.f;
}

【问题讨论】:

    标签: c++ unreal-engine4


    【解决方案1】:

    您应该在BeginPlay 函数中添加动态委托。与设置 Sphere 组件相关的其余代码可以保留在构造函数中。这样做的原因是,在 Unreal 中,如果您先制作蓝图,将其作为 projectile cpp 类的父级,但后来添加了在构造函数中声明的 OnComponentHit 功能,它将无法工作。如果从一开始就使用 cpp 类(包括 OnComponentHit 委托)制作蓝图,它只会在构造函数中工作。这是一个非常常见的问题,经常被忽视。

    如果您还没有这样做,请确保将BeginPlay 函数添加到您的头文件中,

    virtual void BeginPlay() override;
    

    然后在你的 cpp 文件中,声明函数并将你对 AddDynamic 的调用从构造函数移动到 BeginPlay

    void AProjectile_2::BeginPlay()
    {
        Super::BeginPlay();
        Sphere->OnComponentHit.AddDynamic(this, &AProjectile_2::OnHit);
    }
    

    【讨论】:

      【解决方案2】:

      如果您使用 OnOverlapBegin,您的组件应该使用 Overlap 来响应其他组件的碰撞响应,而不是 Block。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-24
        • 2010-11-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-01
        • 1970-01-01
        相关资源
        最近更新 更多