Component Overlap Collisons

I’ve the following code to detect overlap in C++, for some reason it is not working. Which is strange because I have the exact some thing in blueprint that works just fine.

The idea is to have a sword skeletal mesh with a UBoxComponent on the blade part for overlap detection.

SwordWeapon.cpp



#include "CFight.h"
#include "Engine.h"
#include "SwordWeapon.h"


ASwordWeapon::ASwordWeapon(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
	WeaponMesh = ObjectInitializer.CreateDefaultSubobject<USkeletalMeshComponent>(this, TEXT("WeaponMeshComponent"));

	static ConstructorHelpers::FObjectFinder<USkeletalMesh> PrimaryWeapon(TEXT("SkeletalMesh'/Game/Weapons/SwordA/swordb.swordb'"));
	if (PrimaryWeapon.Object)
	{
		// GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, TEXT("Setting Primary Weapon Mesh"));
		WeaponMesh->SetSkeletalMesh(Cast<USkeletalMesh>(PrimaryWeapon.Object));
	}
	SetRootComponent(WeaponMesh);

	BladeComponent = ObjectInitializer.CreateDefaultSubobject<UBoxComponent>(this, TEXT("BladeComponent"));

	BladeComponent->InitBoxExtent(FVector(32.0f, 32.0f, 32.0f));
	BladeComponent->SetRelativeLocation(FVector(-30.0f, 0.0f, 0.0f));
	BladeComponent->SetRelativeScale3D(FVector(0.65918f, 0.166855f, 0.093856f));


	BladeComponent->BodyInstance.SetCollisionProfileName("OverlapAll");
	BladeComponent->bGenerateOverlapEvents = true;
	//SetRootComponent(BladeComponent);

	BladeComponent->OnComponentBeginOverlap.AddDynamic(this, &ASwordWeapon::OnBeginOverlap);

}

void ASwordWeapon::OnBeginOverlap(class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult)
{
	GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, TEXT("OnBeginOverlap Called"));
}



SwordWeapon.h



#pragma once

#include "GameFramework/Actor.h"
#include "SwordWeapon.generated.h"

#define COLLISION_WEAPON ECollisionChannel::ECC_GameTraceChannel1
#define COLLISION_WEAPONTARGET ECollisionChannel::ECC_GameTraceChannel2

/**
 * 
 */
UCLASS(Blueprintable)
class CFIGHT_API ASwordWeapon : public AActor
{
	GENERATED_BODY()

	/** Weapon Mesh*/
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Weapon, meta = (AllowPrivateAccess = "true"))
	class USkeletalMeshComponent* WeaponMesh;

	/** Weapon Blade Box */
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Weapon, meta = (AllowPrivateAccess = "true"))
	class UBoxComponent* BladeComponent;

public:
	ASwordWeapon(const FObjectInitializer& ObjectInitializer);

	UFUNCTION()
	void OnBeginOverlap(class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult);
};


I’ve added a second Box Component ‘Box1’ from the blueprint and offset it slightly downward so both boxes are visible. Collision works from the blueprint box but not the native box.

I’ve tried setting custom profiles and and collision channels on the native box but nothing seems to work. The only time it works is if I set the native box as the RootComponent. But then I loose the skeletal mesh and I need that to attach to the correct socket on my character.

Any ideas?

I don’t see anything immediately wrong with what you’re doing, but here are 2 things you can check. I had an identical issue and it turned out to be that my constructor was not being called during hot reload. Moving the OnComponentBeginOverlap.AddDynamic call to BeginPlay resolved my issue.

The second thing is that overlap events are not generated for skeletal mesh components, so if you are trying to overlap with a skeletal mesh, you’ll never receive the event.

Nope … Assigning the delegate in BeginPlay doesn’t solve the probelm. I’ve worked around the issue by using the Blueprint based Box1 overlap event to manually call the native OnBeginOverlap handler. But this is not a real solution.

I’m running overlap events on a child component of the skeletal mesh, not the mesh itself. If it is not supposed to work on those too then it should also not work for Blueprint based Box1.

This is going to sound totally off the wall, but does it work if you change from creating a UBoxComponent to a USphereComponent?

Two things worth trying:

  1. Make sure the collision box follows the mesh around everywhere:


BladeComponent->AttachParent = WeaponMesh;


  1. Reset collision settings on the collision box after attaching the mesh to the Character’s hand. I’ve noticed at least when attaching Static Meshes to another actor (I used a Static Mesh for swords), collision settings seem to be changed during the process of Attaching, and calling ‘‘SetCollisionProfileName()’’ again AFTER calling ‘‘AttachRootComponentTo()’’ (which I assume you’re using to attach the sword to the character’s hand) may fix your issues. You could also try calling RecreatePhysicsState() on the mesh component.

Yes, you have to Attach your box UBoxComponent to something to make collision and visibility working as i did here:

BoxComponent = CreateDefaultSubobject<UBoxComponent>(TEXT(“BoxCollision”));
BoxComponent->InitBoxExtent(FVector(120, 120, 8));
BoxComponent->AttachTo(RootComponent);