Mouse Cursor Position Not Updating With CPU bound and mouse button pressed

I am using mouse position for drawing a selection Marquee and Panning the Camera (it is RTS like Style Game).

I am using GetMousePosition inside the tick.
In most cases it works fine However I have found an Issue when:

The frame is CPU Bounded (on unlimited engine frame rate (no Vsync, no smoothing no suchj things))
and some of the Mouse Buttons Pressed the mouse position is not getting updated properly - in case it updates once per 2 seconds (approximately not really a time pattern).

For Now I was able to find a work around for Windows and macOS only:

PlayerController.h

#if PLATFORM_WINDOWS
#include "Windows/WindowsSystemIncludes.h"

#include "AllowWindowsPlatformTypes.h"
#include <Windows.h>
#include "HideWindowsPlatformTypes.h"
#endif //Windows

   #if PLATFORM_MAC
private:
#import <Cocoa/Cocoa.h>    
    NSWindow * m_windowHandle;
#endif

#if PLATFORM_WINDOWS
private:
	HWND m_windowHandle;
#endif

PlayerController.cpp

void APlayerController::BeginPlay()
{
    Super::BeginPlay();
//    bShowMouseCursor = true;   
    #if PLATFORM_MAC
        NSArray * windows = [[NSApplication sharedApplication] windows];
        m_windowHandle = windows[0];
    #endif

	#if PLATFORM_WINDOWS
		m_windowHandle = GetActiveWindow();
	#endif
 //...
 //...
 //...
}


void APlayerController::Tick( float DeltaSeconds )
{
    Super::Tick(DeltaSeconds);
    
    //Get ViewPortSize
    // (0,0) is at top left
    int32 viewportX, viewportY;
    GetViewportSize(viewportX, viewportY);
    
    float mouseX = 100, mouseY = 100;
    
    //If Window in focus
    bool windowInFocus = true;
    bool mouseInsideWindow = true;
    
	//Mouse warp for Mac
    #if PLATFORM_MAC
        windowInFocus = (bool)m_windowHandle.isKeyWindow;
        if(windowInFocus)
        {
            //If Window is in focus -> we must ensure the MouseWarp
            NSPoint mouse = [NSEvent mouseLocation];
            bool bx = false ,by = false;
            //If - Mouse is inside the Window we don't care!
            if(!CGRectContainsPoint((CGRect)m_windowHandle.frame, (CGPoint)mouse))
            {
                mouseInsideWindow = false;
                //WarpX
                if (mouse.x < m_windowHandle.frame.origin.x)
                {
                    mouseX = 0;
                    bx = true;
                }
                else if(mouse.x > m_windowHandle.frame.origin.x + m_windowHandle.frame.size.width)
                {
                    mouseX = viewportX;
                    bx = true;
                }
                
                //WarpY //Y has opposite coordinates in unreal
                if (mouse.y < m_windowHandle.frame.origin.y)
                {
                    mouseY = viewportY;
                    by = true;
                }
                else if(mouse.y >= m_windowHandle.frame.origin.y + m_windowHandle.frame.size.height)
                {
                    mouseY = 0;
                    by = true;
                }
                
                float temp;
                if(bx && !by)
                {
                    //get y
                    GetMousePosition(temp, mouseY);
                }
                else if (by && !bx)
                {
                    //get x
                    GetMousePosition(mouseX, temp);
                }
            }
        }
        else
        {
            //macOS Escape
            return;
        }
    #endif
    
//Do mouse warp for Windows ://
#if PLATFORM_WINDOWS
		POINT p;
		if (!GetCursorPos(&p))
		{
			//cursor position now in p.x and p.y
			return;
		}

		if (!ScreenToClient(m_windowHandle, &p))
		{
			//p.x and p.y are now relative to hwnd's client area
			return;
		}

		mouseX = (float)p.x;
		mouseY = (float)p.y;
#endif

		//if play in editor get the mouse as is.
		if (GetWorld()->WorldType == EWorldType::PIE)
		{
			GetMousePosition(mouseX, mouseY);
		}

           //At This Point The Mouse Coordinates will be stored in mouseX, mouseY float variables.

//...
//...
//...
}

Is there a better nicer way to fix it ?

Hey -

Out of curiosity, is this code the cause of the issue or solution? If this is the solution, can you provide the setup you’re using that causes the problem to help me test your issue locally?

When referring to setup, what I mean is what would I have to do when creating a new project to see the behavior that you’re reporting? After creating the project, are there any custom classes being added or blueprints created?

Hey ,

Sorry English is my 4th language, I am not tso good in it.
The code I pasted is the work around (Solution) it is lengthy and ugly :frowning: but works - Yes I can live with this solution ,but I hope for the proper fix.

I am sorry sir, bur what do you mean by setup ?
I use Windows 10
Intel i7 6700k
32gb ram
Nvidia GTX 980ti OC 6gb vram
emm am I missing something

on Mac Side - Latest MacOS Sierra with latest update
Mac book pro 2013 with nvidia 750m 2gb vram
16 gb ram i-7 2.3 ghz (not sure what model) - crystalwell something

Oh I belive you are asking how to reproduce this issue:
Well simpliest way I can find so far:
Create new project (top down I believe) use custom PlayerController.cpp
override the tick make some really heavy calculation on the main thread lets say calculate 20k distances inside the tick and then call ‘GetMousePosition’ and print it’s output to the screen (2float values) you will see it working perfect in PIE but in stand alone game when you are pressing a mouse button e.g. LMB the values of mouse X Y will stop updating (will freeze) - I believe it is the minimal setup (ofcourse I also have an event on LMB pressed and released where I set the bool value of pan/draw selection) maybe you will need it to.

Maximum I can send my own project to a private mail or idk how is it done here).

If you’re able to upload the project (to google driver or something similar) you can provide a download link for the project. If privacy is a concern, you can send me a PM on the forums with the download link.

Hi, yes privacy is a real concern :slight_smile:
It weights about 2GB I will put for an upload tonight - I will also try to modify the source with some #define so you will be able to conditionally test and see the issue by specifiying a #define.
I will try to find a way to send a private message tomorrow after the full upload then.

https://forums.unrealengine.com/member.php?14493--

As I understand you wasn’t able to recreate the issue.
Seema like it comes in conjuction with more things then.

BTW if you could give me a link where I can PM you it will be helpful :slight_smile:

Hey ,
Just too curious, were you able to look in to the project ? :slight_smile:
Roma.

Hey -

I tested the project you provided and I believe what you’re seeing would be expected in this case. Given your repro step of “calculate 20k distances inside the tick” it would be expected that this would cause the thread that is running this calculation to become overloaded. Calling GetMousePosition() in this case would be delayed if the thread is too busy finishing calculations. Your #define PLATFORM_SPECIFIC_FIX appears to help in your case and I would continue using it on your end.

Cheers

Hello ,

I am strongly disagree with you.
Yes in the project I’ve provided there is a hard CPU overload - however this issue can be seen even if a CPU takes Slightly more time than GPU for example:

GPU time 2.2ms and CPU 2.4 if there is no Vsync in this case mouse position will rarely be updated when button is clicked also please note that mouse position updates fine when LMB is not clicked or when LMB double clicked and hold.

Please add on screen message to print mouseX and mouseY inside the tick then you will see it more clearly.