Hello, everyone!
I’m working on a UE v5.3.2 C++ & Blueprint project (mostly the former).
I’m currently experiencing some issues with the UI. The worst of it all is the function SetShowMouseCursor or, in general, the way the porperty that shows the cursor is handled. I’m unable to toggle the cursor visibility at runtime correctly, no matter what I try to make it work.
Here is the best solution (so far) I’ve implemented:
- Created a PlayerController that switches between my PlayerCharacter and a Pawn that I use specifically for the UI (a workaround for another issue);
- Emitted a delegate that broadcasts from the Pawn class everytime it registers a mouse movement (the most effective way was to create an Input Action and bind it to the mouse XY axes);
- Put the delegate subscription in the controller’s BeginPlay function, which calls another function that handles the visibility of the mouse cursor;
// HybridController.h
// ...
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HybridController")
TSubclassOf<AUIPawn> PawnClass;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HybridController")
TSubclassOf<ACustomCharacter> CharacterClass;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "HybridController")
AUIPawn* SpawnedPawn;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "HybridController")
ACustomCharacter* SpawnedCharacter;
// ...
------------------------------------------------------------------------
// HybridController.cpp
void AHybridController::BeginPlay()
{
Super::BeginPlay();
if (PawnClass)
{
FActorSpawnParameters SpawnParams;
SpawnParams.Owner = this;
SpawnParams.Instigator = GetPawn();
FVector ActorSpawnLocation = GetPawn() ? GetPawn()->GetActorLocation() + FVector(200, 0, 0) : FVector(0, 0, 200);
FRotator SpawnRotation = FRotator::ZeroRotator;
SpawnedPawn = GetWorld()->SpawnActor<AUIPawn>(PawnClass, ActorSpawnLocation, SpawnRotation, SpawnParams);
SpawnedPawn->OnToggleShowCursor.AddDynamic(this, &AHybridController::ToggleShowCursor);
}
// ...
}
// ...
void AHybridController::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (bUIMode && SpawnedPawn)
{
SpawnedPawn->DelegateTick(DeltaTime);
}
else if (!bUIMode && SpawnedCharacter)
{
SpawnedCharacter->DelegateTick(DeltaTime);
}
}
void AHybridController::ToggleShowCursor(bool bShow)
{
GEngine->AddOnScreenDebugMessage(2, 1.0f, FColor::Green, FString::Printf(TEXT("TOGGLE CALLED!")), true);
if (bShowMouseCursor != bShow) SetShowMouseCursor(bShow);
}
------------------------------------------------------------------------
// UIPawn.h
// ...
private:
float MouseVisibleTimer = 0.f;
bool bMouseVisible = false;
------------------------------------------------------------------------
// UIPawn.cpp
// ...
void AUIPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
if (UEnhancedInputComponent* Input = Cast<UEnhancedInputComponent>(PlayerInputComponent))
{
// ...
Input->BindAction(IA_Mouse, ETriggerEvent::Started, this, &AUIPawn::HandleMouseMove);
Input->BindAction(IA_Mouse, ETriggerEvent::Completed, this, &AUIPawn::EndMouseMove);
}
}
// ..
void AUIPawn::DelegateTick(float DeltaTime)
{
if (MouseVisibleTimer > 0.f)
{
MouseVisibleTimer -= DeltaTime;
}
else if (bMouseVisible)
{
MouseVisibleTimer = 0.f;
bMouseVisible = false;
OnToggleShowCursor.Broadcast(false);
}
}
// ...
void AUIPawn::HandleMouseMove()
{
bMouseVisible = true;
OnToggleShowCursor.Broadcast(true);
}
void AUIPawn::EndMouseMove()
{
MouseVisibleTimer = UIConstants::CursorVisibilityDuration; // 5.0f
}
Despite the efforts, this implementation hides the cursor when MouseVisibleTimer becomes <= 0 (desired behaviour), but takes around 1-2 seconds to make it visible again after i start moving the mouse (IF it makes it visible AT ALL).
The worst thing is, the test log gets printed EXACTLY when it should (as soon as the mouse starts moving and 5 seconds after the last movement was detected).
Another thing worth mentioning is that both these classes have blueprint children.
Also, I used the “Standalone Game” and the “Selected Viewport” symulation modes.
Am I missing something? Is it possible that Blueprint override something that I missed?
Any help would be appreciated.