setting CurrentMouseCursor only works after a mouse click

I want to change the mouse cursor for an actor for “cursor over”.
My code:



void
AMyClass::NotifyActorBeginCursorOver()
{
	if (GEngine)
	{
		GEngine->AddOnScreenDebugMessage(-1, 3.f, FColor::Cyan, TEXT("NotifyActorBeginCursorOver:: Mouse Over"));
	}

	APlayerController* pPc = GetWorld()->GetFirstPlayerController();
	if (pPc)
	{
		GEngine->AddOnScreenDebugMessage(-1, 3.f, FColor::Cyan, TEXT("NotifyActorEndCursorOver:: PlayerController IS here"));
	        pPc->CurrentMouseCursor = EMouseCursor::Hand;
	}
}


I get for mouse overs always both outputs.
When I just started the game, nothing happens but the output on the screen.

When I left click once,
then I always get the correct mouse cursor when the above code is executed.

Any ideas?

I did the blueprint variant, that works. But I’d prefer to do it in C++.

Not sure if this is even the same problem, but just in case, here a link to an old topic: https://answers.unrealengine.com/questions/140503/currentmousecursor-set-in-playercontroller-is-only.html

Update:
So I wanted to use the Blueprint variant until I find the problem in C++, I have now the same problem if I do it via Blueprint. :frowning:

(removed, because it was not true)

Ok, the problem is completely different than I thought.

I create the level and show an UMG menu.
Everything is ok.
As soon as I click one of the UMG controls (even if I do nothing then), the GetFirstPlayerController seems to be not active anymore.
I click in the world, everything ok, I click the UMG button/canvas, the GetFirstPlayerController is not active.
I can play this game endlessly.

So, how do I put the control back to the PlayerController after clicking the UMG GUI?

[solved]

I got it.
In case someone is interested:



void 
AMyGameGameMode::allowInputUiOnly(UUserWidget* pWidget)
{
	FInputModeUIOnly inputMode;
	inputMode.SetWidgetToFocus(pWidget->GetCachedWidget() );
	APlayerController* pPc = GetWorld()->GetFirstPlayerController();
	pPc->SetInputMode(inputMode);
}

void 
AMyGameGameMode::allowInputGameOnly()
{
	FInputModeGameOnly inputMode;
	APlayerController* pPc = GetWorld()->GetFirstPlayerController();
	pPc->SetInputMode(inputMode);
}

void 
AMyGameGameMode::allowInputGameAndUi()
{
	FInputModeGameAndUI inputMode;
	inputMode.SetLockMouseToViewport(false);
	inputMode.SetWidgetToFocus(nullptr);
	APlayerController* pPc = GetWorld()->GetFirstPlayerController();
	pPc->SetInputMode(inputMode);
	FSlateApplication::Get().SetUserFocusToGameViewport(0);
}



It is important to call only one of these in a short time.
If you have code which calls first one of the above methods and then another one, chances are, it will not work. Clean your code.
I do only use allowInputUiOnly and allowInputGameAndUi, because I don’t like that allowInputGameOnly holds the cursor hostage inside the game window.

3 Likes

I ended up solving this for my project like this in C++:

void AVeilPlayerController::SetMouseCursor(TEnumAsByte<EMouseCursor::Type> NewCursor)
{
	CurrentMouseCursor = NewCursor;

	/*Force the new cursor to show even when no cursor input*/
	float X, Y = 0.f;
	GetMousePosition(X, Y);
	SetMouseLocation(X, Y);
}