Mouse Position Values not correctly updating

Hey,

I just found a bug! And it’s really interesting. I needed a lot of time to reproduce it, and finally I was able to do so in a new project.

There are 4 conditions which all have to come together to experience that bug:

  1. Have a CanvasRenderTarget2D that is updated every tick. It can be empty, like in my project.
  2. Have something in your scene so that you have less than 60fps. I have just placed a lot of lights for that.
  3. Play the Game in Standalone. You won’t experience this bug in PIE, only in standalone and packaged.
  4. Hold your left mouse button (it works with other buttons too) and move your mouse. The mouse X/Y position will no longer correctly update in your game. Any logic where you get the Axis Values for the mouse or the ViewportMousePosition will stop working. The mouse position seems to freeze all the time and only update every few seconds

You can download a repro project here, it’s just a blank new project with 4 or 5 BPs and it’s only 2 MB!

Hi ,

Unfortunately I am not seeing any error in the project you linked. Other than a drop in the tick rate, which is explained by the lowered FPS, there doesn’t seem to be any error in mouse position tracking. Are there any other steps I can take to reproduce this on my end?

Hi !

You don’t see any error? Are you using the same version I use (4.10)? Have you played the game in standalone? How many fps do you get in that scene?

Do you see the mouse position value that is printed out? It never shows the same value for multiple frames while you move the mouse?

I did try it in standalone with a framerate of ~25-30. I did not see any errors with the mouse position printing for multiple frames, if I left the mouse position alone or moved it to the edges of the screen and continued moving in the same direction it continued to print the same position each tick as expected. What framerate are you seeing with the project? If it is too low it may be having difficulty keeping up with mouse position updates.

My framerate is ~50 fps. I just placed as many lights as needed for being slightly below 60 fps.

If you don’t move the mouse or it’s at the edge you can’t see the problem, but if you just regularly move it around on the screen while holding the left mouse button you would directly feel it. If you don’t feel a difference between moving the mouse with mouse button pressed and without mouse button pressed, you don’t see the issue.

If you don’t see the issue then it might only happen on specific hardware. I am using an Intel i7 5820k and a R9 390 GPU.

Hi ,

I just wanted to let you know we are still looking into this. I haven’t been able to reproduce it as of yet but I have a few more tests to run. If in the meantime you find additional repro steps or information that could help us to determine what is occurring, please post it here.

Hi , thanks for the update.

I have just asked someone in slack to download it, and he directly saw (or felt) the bug, so it’s definately not only happening here on my PC.

His hardware is this: Intel i7 2600, GeForce GTX 760

After more testing, we are still not seeing this occur internally. The update seems to be working as intended, even at lower framerates. Is there anything else I can try to reproduce this on my end?

I have no clue how that can be. You do everything as I said? You run it in standalone (not PIE) and you hold the left mouse button while moving the mouse around? With holding the left mouse button it should feel like less than 1fps, without holding it it feels like the correct 25-30fps you get.

Should I ask more people to test it?

I’ve taken a video of how it looks like here.

It did not capture my mouse cursor, but I’m moving it all the time. You see how the output shows the same location for multiple frames and that it looks super laggy even though my fps are at constant 55.

Then I release the left mouse button and suddenly it’s running perfectly smooth and mouse position update correctly.

Video

What software do you currently have open with the editor when this occurs? I noticed that I see something similar while I was attempting to record what was occurring on my end, however it does not occur normally. Additionally, is your mouse cursor outside of the standalone window when this occurs? What is your mouse sensitivity set to?

It can’t occur if the mouse cursor is outside of the game window, since then the cursor is not used in the game.

I don’t see a difference between recording or not recording.

I always have quite a lot of software running, Skype, Slack, Epic Launcher, multiple windows of Chrome, Teamspeak, Steam, Avast, Samsung Magician, Dolby Sound stuff, Crashplan.

But I don’t think this has to do anything with the software that is running, that would be quite strange since it’s caused by the CanvasRenderTarget2D of UE4.

I have sent the project to 3 people, 2 of them see the bug and 1 does not. You also don’t. So including me and you, on 3 PCs its happening while it isnt on 2.

My mouse sensitivity, do you mean in windows? It’s set to this:

http://puu.sh/lQycY/798245935b.png

Hey there, just want to add some information to it:

I also experience what he describes. If you start the Game in Standalone (or package it etc), and you look to the ground which will lower the FPS cause of all the lights, it will start shuttering while holding the left mouse button and moving.

Normally the camera should move smoothly, even with low fps, but this here is sometimes not even moving an inch.

What resolves this issue is either setting the tick in the HUD Blueprint to tick in like every .1 sec (note that this tick prints the mouse data that appears to lag then, but that’s only due to the changed tick).

Or to add this to the BeginPlay of the PlayerController:

http://puu.sh/lR1ns/48347a99af.png

Why this is happening in the first place? I don’t know. I guess that’s up to the Epic devs to solve :smiley:

Hi ,

I was finally able to reproduce it following the steps listed, however it is still extremely inconsistent and I was only able to repro it once out of ~12 attempts. I went ahead and put in a bug report, UE-24374, to be assessed by the development staff, including the steps listed here as well as a note reporting that it may take multiple attempts to adequately reproduce. For now, 's workarounds seem like the best solution to the error.

Hi , is there any update on this yet?

Didn’t find a link to UE-24374 bug, so I post it in this thread.


Just spent 6 hours on this one, lucky that someone else noticed that as well.

I will give you hints on what is going on there.
The code around mouse processing works in very weird way, having async where it shouldn’t be: it gets current mouse position values straight using WINAPI calls, not using what WM_MOUSEMOVE provides.
Thus, the result of very same code calls will depend on data synchronization between OS and UE4, and in case of big delays (low FPS issue) we have racing issue and the code breaks.

More specifics on the bug. It happens at FSlateApplication::ProcessMouseMoveEvent:
If no mouse button pressed, we run through common flow of broadcasting
CurWidget.Widget->OnMouseMove(…)
that, in turn, will update last mouse cursor position variable deep inside viewport code. And no problem.

Though, if we hold a mouse button, engine considers this as mouse capture case and things are very different now.

GOOD CASE:

  1. WM_MOUSEMOVE processing notice that mouse position changed from previous frame.
  2. FSlateApplication.ProcessMouseMoveEvent, bIsSynthetic=0 is called
  3. It invokes SViewport::OnMouseMove and CachedMousePos is updated
  4. FSlateApplication::PointerIndexLastPositionMap[CursorPointerIndex] is updated
  5. User code runs with updated mouse position
  6. FSlateApplication.ProcessMouseMoveEvent, bIsSynthetic=1 is called
  7. Mouse position is changed again(!), so FSlateApplication::PointerIndexLastPositionMap[CursorPointerIndex] is updated
  8. – next frame –
  9. WM_MOUSEMOVE processing notice that mouse position changed from previous frame…

Will be similar positive outback if two WM_MOUSEMOVE events will be processed same frame.

BAD CASE:

  1. WM_MOUSEMOVE processing sees that mouse position didn’t change.
  2. FSlateApplication::PointerIndexLastPositionMap[CursorPointerIndex] is updated, with latest Windows mouse location(!)
  3. User code runs with old mouse position (i.e. mouse didn’t move for user code)
  4. FSlateApplication.ProcessMouseMoveEvent, bIsSynthetic=1 is called
  5. FSlateApplication::PointerIndexLastPositionMap[CursorPointerIndex] is updated to latest Windows mouse location
  6. – next frame –
  7. WM_MOUSEMOVE processing notice that mouse position didn’t change since step 6…

Code solution could be to comment out
if ( !bIsSynthetic )
check at FSlateApplication.ProcessMouseMoveEvent. So final code should look like this:

	FWidgetPath MouseCaptorPath;
	if (MouseCaptor.HasCaptureForPointerIndex(MouseEvent.GetPointerIndex()))
	{
		//MouseCaptorPath = MouseCaptor.ToWidgetPath(MouseEvent.GetPointerIndex(), FWeakWidgetPath::EInterruptedPathHandling::ReturnInvalid);
		MouseCaptorPath = MouseCaptor.ToWidgetPath(FWeakWidgetPath::EInterruptedPathHandling::ReturnInvalid, &MouseEvent );
	}

	if (MouseCaptorPath.IsValid())
	{
//		if ( !bIsSynthetic )
		{
			// Switch worlds widgets in the current path
			FScopedSwitchWorldHack SwitchWorld( MouseCaptorPath );
			
			FReply Reply = FEventRouter::Route<FReply>( this, FEventRouter::FToLeafmostPolicy(MouseCaptorPath), MouseEvent, [this]( const FArrangedWidget& MouseCaptorWidget, const FPointerEvent& Event )
			{

As for non-captor case, now the MouseMove will be called twice, but only one will make it to the Viewport, as Viewport has internal check for cursor position change as well.

Please keep me informed what would be the correct solution on the problem. I would recommend to run refactoring and get rid of direct calls to FWindowsCursor::GetPosition()

Hi John,

Unfortunately, our resources are currently dedicated elsewhere. I do not have a timeframe of when or if a fix will be implemented for this, though I would not expect one in the near future.

Hi Johny, thanks very much for this detailed description of the problem. I’ve tested your fix (comment out if ( !bIsSynthetic )) and it works very well! I don’t want to use a custom build of the engine though, so I hope it get’s fixed soon in a new version or a hotfix.

Update: For 4.11, the code above was relocated to
FSlateApplication::RoutePointerMoveEvent
File SlateApplication.cpp
Line 4727

Commenting out if ( !bIsSynthetic ) still does the trick.