OnComponentHit not fired if Character is moved slowly

I have correctly set up my Character in the following way:
CapsuleComponent->OnComponentHit.AddDynamic(this, &AMyCharacter::onHit);

And added the method:
void AMyCharacter::onHit(AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)

I move the Character using, as in the Shooter Sample:
AddMovementInput(GetActorForwardVector(), Value);

The floor is set using Static Meshes. However, if I move my character slowly with a relative low value or short time, the Hit event not gets triggered. If I run constantly it gets called every frame. What could cause this issues?

Thank you for your answers!

I would suggest to not implement your own OnComponentHit() but use instead the virtual method ReceiveHit.

On the FP template, this can potentially conflict with other actors own OnHit() signatures spawned by the character. This may not happen to you immediately as you seem to refer to the FPS tutorial and building the solution from scratch, but it’s a better practice, I believe.

Regards.

Thanks for the heads up DrHobo! I’ve switched to overriding the ReceiveHit() method, but the result is the same.

I need this because I’ve generated a tile-based map, constructed of static meshes, and I would like to detect which Tile is the Character standing on. If you can propose a better way to do it, I would appreciate it as well!

I’m experimenting with the function, so thet content does not really matter. Right now, I spawn my tiles with blue material, and upon the Character receives a hit, I change the other Actor’s material to orange, if it is a Tile. As the static meshes are built from blueprints and are set to react to physics (the block available in the Puzzle sample), I do get correct hit events if I’m constantly moving with my character, but when just pressing the Up arrow for short periods, the ReceiveHit() event not gets fired.

Well I’m not sure the kind of results you were expecting as both OnComponentHit() and ReceiveHit() work with Actors, not simply Solid Meshes. With ReveiveHit(), solid meshes will generate a hit, but you won’t be able to identify them, only which component from your character received the hit (that’s another advantage for using ReceiveHit() if you want to add multiple components for your character instead of implementing a separate OnHit() for each component.) As for the speed, I tested speed as slow as Max Speed = 20, or standing still while receiving a block on the head and still generated a hit. So, unless I’m misunderstanding something, and the fact that you might be building this whole solution from scratch, there’s maybe more to it. What’s the content of the method, BTW ?

Of course not. :slight_smile: Walking on the object does not constitute a hit. LOL. I’m reading the original post and I should’ve seen this, although it’s not very clear from the context.

I would suggest using a mesh collider a smidgen larger for your tiles and use OnComponentBeginOverlap() and OnComponentEndOverlap() instead to trigger and untrigger the walking sequence - or rather the character’s own OnActorBeginOverlap() . As you overlap, a signal is sent and as you stop overlapping, another signal is sent.

I’ve first started implementing the Overlap events, but they didn’t get fired at all. I was also surprised that the mesh actually generates Hit events as the character walks on them. Thanks for the help anyway, I will try to set another mesh over the static one to generate overlaps, and get back with the results.

Out of curiosity, is this what you are looking for ?

Exactly that. I couldn’t find a quick way to edit a static mesh to have another layer on them, I guess I will need to create a blueprint out of it, or edit in 3DSMax, which I’m also not familiar with currently. Can you share the details how did you achieve this, if it differs from the previous ideas discussed above?

Sorry for using another answer slot. The comment box refuse my (long) answer.

Well, it’s different: I looked at the problem again and I focused on the tile instead of the character. Unless you really want to identify which of its component was hit (other then his feet), you can simply use this scheme to apply damage back to it with minimal fuss.

The static mesh is taken directly from the puzzle template.
I created the collision component in the constructor with dynamic overlapping detection. Then I created a Blueprint and added the mesh as a child in the editor.

ATile::ATile(const class FPostConstructInitializeProperties& PCIP)
: Super(PCIP)
{
    // Use a box as a simple collision representation
    CollisionComp = PCIP.CreateDefaultSubobject<UBoxComponent>(this, TEXT("BoxComp"));
    CollisionComp->InitBoxExtent(FVector(250, 250, 20));
	CollisionComp->OnComponentBeginOverlap.AddDynamic(this, &ATile::OnTileBeginOverlap);
	CollisionComp->OnComponentEndOverlap.AddDynamic(this, &ATile::OnTileEndOverlap);
        CollisionComp->SetCollisionProfileName(FName(TEXT("OverlapAllDynamic")));

    RootComponent = CollisionComp;
}

Then change the color when you enter the tile’s collision zone. I use a dual color scheme in the material with a parameter change to lerp between both colors.

void ATile::OnTileBeginOverlap(class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult)
{
    // Use OtherActor to identity character and apply damage.

    if (TileMID)
        TileMID->SetVectorParameterValue(FName("ColorProgress"), FVector(1.0f));
}

As you leave, bring the param to 0.

void ATile::OnTileEndOverlap(class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex )
{
    // Use OtherActor to identity character and apply damage.

    if (TileMID)
        TileMID->SetVectorParameterValue(FName("ColorProgress"), FVector(0.0f));
}

I use OnTile… to avoid name mangling errors due to Blueprints who might have similar names, just like I told you before.

Thank you very much DrHobo! This is the solution I was looking for. I went on a slightly different path, added only the collision component in the constructor and still detecting the Overlap events in the character (this would be important in the future), and it works like a charm. I’m still experimenting with the engine, as it is only the fourth day I’m working with it. :slight_smile: Thanks again!