OnBeginCursorOver not working, C++ & mouse hover

I have this simple setup where I wish to test if I can trigger mouse hover effect on a Actor.
After reading posts regarding this topic I came to the following code. AUnitBase is a Pawn Class, I create a StaticMesh component and assign OnBeginCursorOver to trigger a function. Like so

StaticMeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("StaticMesh"));
	StaticMeshComponent->SetupAttachment(SkeletalMeshComponent);	
	StaticMeshComponent->OnBeginCursorOver.AddDynamic(this, &AUnitBase::OnMouseOver);

OnMouseOver is a simple log function

void AUnitBase::OnMouseOver(UPrimitiveComponent* TouchedComponent)
{
	UE_LOG(LogTemp, Warning, TEXT("Mouse hover"));
}

Then In editor I have BP class based on AUnitBase and its in game area. I press Play in editor and then try to move mouse over this static mesh but nothing gets logged.
What else do I need to do to make this work ?

Hey @Ettu_R, welcome to the forum community!
I believe you have to enable clickable in your mesh component. I found another forum question that might help:

Let me now if this helps!
-Zen

Thank you for reply @ZenLeviathan
I managed to get it working, sort of …
What I did was create a custom PlayerController for my PlayerPawn. Then in that controller I added

        bShowMouseCursor = true;
	bEnableMouseOverEvents = true;

So now mouseover works. However, as I’ve read it will only work on StaticMesh ? I tried to add this to SkeletalMesh and that does not trigger mouseover ?

SkeletalMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("SkeletalMesh"));
	SkeletalMeshComponent->SetupAttachment(CapsuleComponent);	
	SkeletalMeshComponent->OnBeginCursorOver.AddDynamic(this, &AUnitBase::OnMouseOver);

Is there any way I can make it work on SkeletalMesh ?

I have this dragon, which is animated and that I would like to have mouseover effect on. How can I make it so that mouseover works on that dragon ?

I made BluePrint from this C++ class and inside BluePrint, when I look at SkeletalMesh component, there seems to be possible to register mouse events. I added one like so

However this does not trigger.

I think I figured it out! I changed collision preset on SkeletalMesh to “OverlapOnlyPawn”, which I believe now triggers mouseover from my PlayerPawn. Seems to work as I wanted :slight_smile:

1 Like

@Ettu_R
Glad you figured it out, and sorry I couldn’t respond sooner! Thanks for posting your solution too!
Happy Developing!
-Zen :vulcan_salute:

I have a situation I dont quite understand comparing C++ / BluePrint.
I have C++ baseclass and BluePrint made from that base.
When I try to make SkeletalMeshComponent to trigger hover effect through C++ it wont work, so the following code wont trigger

SkeletalMeshComponent->OnBeginCursorOver.AddDynamic(this, &AUnitBase::OnMouseOver);
	SkeletalMeshComponent->SetCollisionResponseToChannel(ECollisionChannel::ECC_Pawn, ECollisionResponse::ECR_Overlap);

But if I got to blueprint, select SkeletalMeshComponent and manually set Collisionchannel to only overlap Pawn and add OnBeginCursorOver event through blueprint, it will work.

What is missing to get it working through C++ ?

I had a lot of problems getting OnBeginCursorOver to fire in my Actor subclass in C++. I tried a lot of different approaches on various posts and nothing worked.

Commenting here because this post has had a lot of views and other posts I found expressed similar frustrations.

In the end this worked for me. Turn it on in the APlayerController subclass:

AAdventurePlayerController::AAdventurePlayerController()
{
	SetShowMouseCursor(true);
	bEnableMouseOverEvents = true;
}

…then in the static mesh actor:

void AHotSpot::BeginPlay()
{
	UStaticMeshComponent* StaticMeshComponent = GetStaticMeshComponent();
	if (StaticMeshComponent && StaticMeshComponent->GetStaticMesh())
	{
		StaticMeshComponent->SetCollisionEnabled(ECollisionEnabled::Type::QueryOnly);
		StaticMeshComponent->SetCollisionResponseToChannel(ECollisionChannel::ECC_Pawn, ECollisionResponse::ECR_Overlap);
		StaticMeshComponent->SetGenerateOverlapEvents(true);

		Super::OnBeginCursorOver.AddDynamic(this, &AHotSpot::OnBeginCursorOver);
		Super::OnEndCursorOver.AddDynamic(this, &AHotSpot::OnEndCursorOver);
	}
}

I did same as you @Ettu_R - with the SetCollisionResponseToChannel but my handlers were messed up (see below).

I also added the line above to set QueryOnly collisions enabled and also SetGenerateOverlapEvents to true.

I also moved the binding of the callbacks to after these flags were set up, just in case.

One thing to note is that the naming of the callback is arbitrary. I had gotten the impression that just naming it that OnBeginCursorOver would work, but of course it doesn’t. You have to bind handlers with these signatures:

	//////////////////////////////////
	///
	/// USER INPUT EVENTS
	///

	UFUNCTION(BlueprintCallable, Category = "HotSpot")
	void OnBeginCursorOver(AActor *TouchedActor);

	UFUNCTION(BlueprintCallable, Category = "HotSpot")
	void OnEndCursorOver(AActor *TouchedActor);

I’m not sure if other handlers with the UPrimitiveComponent argument ever worked. That was what I had before arriving at this.