Collision observations & issues

I’ve been messing about with collision for the last few days, and have a few observations that I don’t understand, hopefully someone can fill in the blanks.

I have setup test project with a simple actor that will crash into a Cube in the editor…

.h

UCLASS()
class COLLISIONTEST_API AMyActorA : public AActor
{
	GENERATED_BODY()
	
public:	
	AMyActorA();

protected:
	virtual void BeginPlay() override;

public:	
	virtual void Tick(float DeltaTime) override;

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

protected:

	UPROPERTY(VisibleAnywhere, Category = "Components")
	class USceneComponent *BaseComp;

	UPROPERTY(VisibleAnywhere, Category = "Components")
	class USphereComponent* CollisionComp;
};

.cpp

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

	BaseComp = CreateDefaultSubobject<USceneComponent>(TEXT("BaseComp"));

//	RootComponent = BaseComp;	// <- No Collision
	BaseComp->SetupAttachment(RootComponent);	// <- Collision works OK

	CollisionComp = CreateDefaultSubobject<USphereComponent>(TEXT("CollisionComp"));
	CollisionComp->SetSphereRadius(32.0f);
	CollisionComp->SetCollisionObjectType(ECollisionChannel::ECC_WorldDynamic);
	CollisionComp->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
	CollisionComp->SetCollisionResponseToAllChannels(ECR_Ignore);
	CollisionComp->SetCollisionResponseToChannel(ECC_WorldDynamic, ECR_Block);
	CollisionComp->SetCollisionResponseToChannel(ECC_WorldStatic, ECR_Block);
	CollisionComp->SetGenerateOverlapEvents(true);
	CollisionComp->SetHiddenInGame(false);
	CollisionComp->SetupAttachment(BaseComp);
	CollisionComp->OnComponentHit.AddDynamic(this, &AMyActorA::OnHit);
}

// Called when the game starts or when spawned
void AMyActorA::BeginPlay()
{
	Super::BeginPlay();
}

// Called every frame
void AMyActorA::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	FVector moveDelta(0.0f, 1.0f, 0.0f);

	FHitResult Hit(1.f);
	RootComponent->MoveComponent(moveDelta, GetActorRotation(), true, &Hit);
	if (Hit.IsValidBlockingHit())
	{
		UE_LOG(LogTemp, Warning, TEXT("ActorA Hit something during move"));
	}

}

void AMyActorA::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
{
	UE_LOG(LogTemp, Warning, TEXT("ActorA Hit Event Fired"));
}

Dragging this class into the level next to a cube that it will hit, works as expected (YAY!)… however, if I make the scene component the root (see comments in constructor), rather than attaching, then there is no collision, none of the hits ever happen?

The second issue I find is that, even if I use the SetupAttachment() call so the collision works, making a Blueprint of this Actor and placing that in the world (rather than the instance of the class) next to the cube… again, no collisions ever happen?

I’ve got both actors setup side by side, next to the cube, but “BP_ActorA” just sails on through :frowning:

I checked the blueprint collision settings and they are as expected (as per the C++ setup), but I never get any collisions at all if this is a blueprint of an actor, rather than the C++ instance of that same actor…

I don’t get it… Can anyone explain what’s causing the collision to fail in either of these “not working” cases?

OK, well the answer seems to be to NOT use a USceneComponent as the root.

I thought this would be OK, but it seems not… removing that, and making the root be the USphereComponent… it all works.

I’d still be interested in why making a USceneComponent the root buggers everything up?