Can't enable Hit Event on Pawn

Hi,

I want to receive a Hit Event when my Pawn bumps into another object. I created my Pawn Class in C++ and Subclassed in in Blueprint. It has a StaticMeshComponent as its RootComponent. I overrode (is that a word? :slight_smile: ) ReceiveHit in C++:

void AShipPawn::ReceiveHit(UPrimitiveComponent * MyComp, AActor * Other, UPrimitiveComponent * OtherComp,
	bool bSelfMoved, FVector HitLocation, FVector HitNormal, FVector NormalImpulse, const FHitResult & Hit)
{
	Super::ReceiveHit(MyComp, Other, OtherComp, bSelfMoved, HitLocation, HitNormal, NormalImpulse, Hit);

	if(Mesh)
	{
		// Whatever ...
	}
}

The event never fires.
I read that I have to enable “Simulation Generates Hit Events”, but the Details Panel in my Blueprint doesn’t show it:

I also tried binding on the StaticMeshComponents’ OnComponentHit Event, but that one doesn’t fire either.

Am I missing something? Can I set the “Generates Hit Event” status form C++?

Edit: I’m using Unreal Engine 4.7.1 btw.

Edit 2: eXi, why have you accepted the answer as correct? It provides a workaround, but I refuse to accept this as a permanent solution to the problem! If I think an answer is sufficient, I will happily accept it myself! Unfortunately I don’t have the permissions to remove the “Accepted” mark. I was hoping for more suggestions regarding this issue. If there is no way to do this in UE4, please simply tell me or let me file a bug report!

Thanks for your Help!

David

Maybe this will help

Added to my class(called Zplane)

Header:

UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = collision, meta = (AllowPrivateAccess = "true"))
	class UBoxComponent* CollisionComp;


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

CPP:

CollisionComp = PCIP.CreateDefaultSubobject<UBoxComponent>(this, TEXT("CollisionComp"));



	CollisionComp->OnComponentHit.AddDynamic(this, &AZplane::OnHit);
	RootComponent = CollisionComp;



//then the onhit class: 

void AZplane::OnHit(AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
{


	if (OtherActor->IsA(ATStestPawn::StaticClass()))
	{
		Destroy();
	}



}

**ATestPawn is my class that " destroys" the hit object(collisionComp in my Zplane class)

If you don’t add the AddDynamic part to the object you want to be hit, it won’t work at all.
hope this helps!

Thanks for your answer, but that’s unfortunately not what I need as a Box is not a very good approximation for my Pawn. I’d like to know when the actual mesh collides.

It doesn’t have to be a box, it can be anything with collision enabled :slight_smile: You don’t have to destroy either, it was more of an example to show how to get onhit to work.

When you put block all, does the object stop when it collides with an object that also has collision enabled?

This actually works. I created a seconds Static Mesh Component with the same static mesh and Visible = False. On the second one I have the Option to enable “Generate Hit Events”. The Event is not properly triggered when I hit something.

But I am far from happy with this solution. This is Unreal Engine 4, a professional game engine, it should have the possibility to generate Hit Events without using a horrible hack :frowning:

Thanks anyway for your workaround. I will try to contact Epic about this issue.

I have found another workaround myself which I’d like to share here. It avoids the inconvenience of a separate collision mesh.

The Problem:

I had a custom C++ Pawn class (AShipPawn) with a static mesh as its root component:

class MOTHERSHIP_API AShipPawn : public APawn
{
    GENERATED_BODY()
public:
    AShipPawn();
    // ...
protected:
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Model, meta = (AllowPrivateAccess = "true"))
    UStaticMeshComponent* Mesh;
};

In the Constructor I created a new Static Mesh Subcomponent.

AShipPawn::AShipPawn()
{
    Mesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
    // Set various fields on Mesh
    RootComponent = Mesh;

}

In Blueprint, I subclassed the AShipPawn class and set the Static Mesh and changed several other properties. As shown in the initial post, I was unable to Enable “Simulation Generates Hit Events”.

The Solution:

Don’t create the UStaticMeshComponent in the C++ class constructor! I simply left the variable with a nullptr value and didn’t even set the RootComponent:

AShipPawn::AShipPawn()
{
    // Actually blank!
}

Then in Blueprint, I used the UI to create a new UStaticMeshComponent, set all the values and the Mesh and assigned my shiny new UStaticMeshComponent as the RootComponent of the Actor. If the Object is created in Blueprint, I can also set “Simulation Generates Hit Events”. Last Problem to solve is that my C++ class needs to manipulate the Mesh during gameplay (AddForce(), AddTorque(), …), but the variable in C++ is still a nullptr.

The solution is a simple Blueprint Construction Script that sets the Blueprint-Generated component as the value of the C++ variable:

31921-capture.png

Make sure that you have “Show Inherited Variables” checked in the Blueprint, otherwise you won’t be able to see the C++ variable.

This process might seem obvious for experts, but it certainly wasn’t for me. I still think this is a bug, but I don’t know how to tell the devs…

I hope this helps someone else.

I got it to work by setting

Mesh->bGenerateOverlapEvents = true;
Mesh->SetNotifyRigidBodyCollision(true);

and overriding ReceiveHit.

<YourPawn.h>

public:
	virtual void ReceiveHit(class UPrimitiveComponent* MyComp, class AActor* Other, class UPrimitiveComponent* OtherComp, bool bSelfMoved, FVector HitLocation, FVector HitNormal, FVector NormalImpulse, const FHitResult& Hit) override;


<YourPawn.cpp>

void YourPawn::ReceiveHit(class UPrimitiveComponent* MyComp, class AActor* Other, class UPrimitiveComponent* OtherComp, bool bSelfMoved, FVector HitLocation, FVector HitNormal, FVector NormalImpulse, const FHitResult& Hit)
{
	Super::ReceiveHit(MyComp, Other, OtherComp, bSelfMoved, HitLocation, HitNormal, NormalImpulse, Hit);

	if (GEngine) {
	GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, FString("HERE Crash with " + Other->GetName()));
	}

}