OnBeginCursorOver.AddDynamic not working in 4.9?

Hey,

I am using this code (in the constructor) to highlight my paws when hovered by the mouse cursor:

OnBeginCursorOver.AddDynamic(this, &AYagObject::HighlightOn);

This has been working forever and doesn’t work anymore in 4.9.

In case it helps, in order to trigger the function, i have to hover the pawn AND left click.

I didn’t change anything in the code, it’s a fresh migration to 4.9.

Thanks

Cedric

Hey -

I tried to test this by creating a project in 4.8.3 and converting it to 4.9. I first created a new class based on actor and setup a static mesh component in the constructor:

MyMesh = OI.CreateDefaultSubobject(this, TEXT("MyMesh"));.

In the BeginPlay function I then got a reference to the game world to enable mouse over events and set my dynamic binding:

UWorld* TheWorld = GetWorld();
	TheWorld->GetFirstPlayerController()->bEnableMouseOverEvents = true;
	MyMesh->OnBeginCursorOver.AddDynamic(this, &AMyActor::OnHover);

The OnHover function was used to print a message to the screen:

void AMyActor::OnHover(class UPrimitiveComponent* OtherComp)
{
	if (GEngine)
	{
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Magenta, TEXT("Hovering"));
	}
}

After compiling I created a blueprint and set a static mesh to the component. This worked to print the “Hovering” message when I moused over the static mesh in both 4.8.3 and 4.9. Could you let me know if this is similar to how your function is setup or if you used another method.

Cheers

Hey ,

What i am doing is quite different, my function is defined with no arguments and the binding is done at the level of the actor

AYagObject::AYagObject(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
	OnBeginCursorOver.AddDynamic(this, &AYagObject::HighlightOn);
	
	...
}

void AYagObject::HighlightOn()
{
	...
}

(the bEnableMouseOverEvents is set to true in the constructor)

This worked before 4.9 and doesn’t now.

My actor contains several static and skeletal mesh components and they were all triggering the function when hovered.

Of course, i tried to do as you do and transformed my code into this

AYagObject::AYagObject(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
	YagObjectBody = ObjectInitializer.CreateDefaultSubobject<UStaticMeshComponent>(this, TEXT("Body"));
	YagObjectBody->OnBeginCursorOver.AddDynamic(this, &AYagObject::HighlightOn);

	...
}

void AYagObject::HighlightOn(class UPrimitiveComponent* OtherComp)
{
	...
}

This code compiles, but the hovering produces nothing.

Moreover, when hovering AND left clicking (which seems to trigger the event and call the function), i get an access violation crash.

Cheers

Cedric

Hey -

I changed my code to match your setup:

Actor Constructor:

AMyActor::AMyActor(const FObjectInitializer& OI)
:Super(OI)
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;
	OnBeginCursorOver.AddDynamic(this, &AMyActor::OnHover);
}

Bound Function:

void AMyActor::OnHover()
{
	if (GEngine)
	{
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Magenta, TEXT("Hovering"));
	}
}

I then added a static mesh in the blueprint and when hovering over the blueprint in game the Hovering message appeared as expected. Could you send me your project so I can test what you’re seeing directly?

Hey ,

The project is to heavy to be sent but i made you a short video to show you the problem, you’ll find it here:
http://yagame.fr/wp-content/uploads/YagCurrentVersion/Doug_Hover_Pb.flv

If you want the code for anything you see on screen (maybe the object on the table), you tell me and i’ll send it to you.

Cheers

Cedric

The video did not play properly (I have the audio but the video is completely fragmented). The OnBeginCursorOver.AddDynamic() method has worked properly for me in the tests that I’ve run. If your project is too large to upload then could you reproduce the issue in a new project and send that instead?

Hey ,

Quite strange for the video, VLC plays it ok in principle, but ok, no problem, let’s do without the video^^

I have tried to reproduce the problem in the following project:

http://yagame.fr/wp-content/uploads/YagCurrentVersion/HoverProject.zip

It’s a TopDown C++ project that i modified:

  • added a hovering function at the level of the character (HighlightOn function), which doesn’t work on my computer

  • tried to add a hovering function on an extra static mesh component, but the component won’t show in game !!! (though it shows in the BP, and HiddenInGame is false, so another mystery for me).

  • so i tried to define the binding on the capsule, but that didn’t trigger the function

In short, none of my tries could trigger any of the two bound functions i defined.

Can you try this project and if yes, do you have the same behavior on your computer ?

Thanks

Cedric

Hey -

I was able to test the project you uploaded. You’re correct that the mouse over event is not triggering however this only appears to be on a character. This has been reported (UE-20801) for investigation.

Cheers

Huuh… so anyone else is experiencing that problem too.
Already uploaded a Bug report about it, but was closed:

For me, the same thing happens on a class derived from AActor. Worked like a charm in 4.8.
Perhaps worth to note is that I had to derive a player controller (in 4.8) to get mouse events going according to this tutorial:

If this might not be necessary anymore in 4.9, perhaps this might be the root cause? Only an idea.
Please fix it. You would make an old man very happy! :wink:
Have a nice weekend!

Hey DerChris,

Interestingly enough, it can work. In the following project (it’s an update from the previous same link) i have set up an actor derived class to be hovered.

http://yagame.fr/wp-content/uploads/YagCurrentVersion/HoverProject.zip

If you try this project, you’ll see that the hovering doesn’t work for the character (as recognized by ), but it works for the actor (the cube beside the character).

Now where it becomes really interesting is that the exact same code doesn’t work when copy pasted from this toy project to my migrated project.

So i guess there must be some sort of interaction (with UI or or i don’t know what) that breaks the mouse event in the full project.

So in principle, by adding elements one by one from my project to the toy project, at one point i should be able to break the hovering on the actor and single out the source of the problem.

Of course i will report if i find anything.

Cheers

Cedric

Hey,

Found Something.

Here is the PostInitializeComponents of my hud.

When i block the execution of Viewport->AddViewportWidgetContent by adding a comment to the line, the hovering is back and ok.

void AYagHUD::PostInitializeComponents()
{
	Super::PostInitializeComponents();
	
	if (GEngine && GEngine->GameViewport)
	{
		// get viewport
		UGameViewportClient* Viewport = GEngine->GameViewport;

		// mother widget that contains everything
		SAssignNew(YagHUDWidget, SYagHUDWidget)
			.YagHUD(TWeakObjectPtr<AYagHUD>(this));

		// add the mother widget
		// WHEN COMMENTING THIS LINE, THE HOVERING WORKS FINE
		//Viewport->AddViewportWidgetContent(SNew(SWeakWidget).PossiblyNullContent(YagHUDWidget.ToSharedRef()));
	}
}

So That’s definitely a problem of interaction with the UI that appeared with 4.9 migration (thanks DerChris for pointing me to the UI).

Cheers

Cedric

It sounds like it is a problem with the cursor colliding with the widget, not the OnBeginCursorOver event per se. I would suggest using the ‘Widget Reflector’ to determine which widget is being hit, and disabling hit testing with it.

Hello JamesG,

The culprit is the main widget, which takes all the screen and is a container for all the other widgets if the game UI.

I couldn’t find a way to disable hit testing in c++.

I found an OnHitTest function but i guess when it’s called it’s already too late.

Do you know how to do this in code ?

Thanks

Cedric

Hello,

Any idea about how to prevent this hit testing thing in c++ ?

I am very interested in any workaround, as my game is mostly unusable at the moment.

Thanks

Cedric

Hey -

This is assuming that your main widget is just the default canvas panel with the other UI widgets as a part of it. You can select the Canvas Panel of the main widget and in the details panel set the Visibility drop down to Self Hit Test Invisible. This should cause only the main widget to ignore hit tests but not affect any of its children so you can still use the other UI elements.

Hey ,

Thanks for the pointer, i could translate this into c++:

YagHUDWidget->SetVisibility(EVisibility::SelfHitTestInvisible);
YagHUDWidget->SetVisibility(EVisibility::HitTestInvisible);

I tried one, the other, and both, and unfortunately it didn’t change anything.

I’m all ears for any other workaround idea^^

Thanks

Cedric

update update, it worked !

Apologies, i had placed the code before adding the widget to the viewport.

Thanks a lot , again !

This solved it for me also.
I previously tried to set only the canvases of the menus to EVisibility::SelfHitTestInvisible, but that didn’t do it. Setting the whole menu worked like a charm. Interestingly it’s buttons still work if menu is set to EVisibility::SelfHitTestInvisible.

Thank you!