This seems like a bug in the Android implementation of Mouse.
The goal is to use a usb/wired mouse to control player rotation similar to a FPS game on PC.
I’m using Mouse.current.delta.ReadValue() to determine how much to rotate, however this behaves differently on PC vs Android.
- On PC I can move the mouse to the right forever and delta.x will always be > 0 as it’s moving, even if Mouse.current.position is clamped at the right edge of the window (CursorLocked).
- On Android it appears the delta.x is computed as a change to the position, so it becomes 0 when the position is clamped at the right edge of the window.
This difference in behavior breaks my assumption that the delta is wrt physical mouse movement and not cursor position changes. The result is that the player can only rotate so far to the right/left before their inputs start getting ignored.
Is this a known issue, and any suggestions to work around it?
tested on: Oculus Quest 2, Unity 2021.3.4f1, Input System 1.3.0
1 Like
Ok I’ve confirmed this is a Unity bug on Android (or potentially just Quest 2).
I made my own java activity and I can see that we are getting events that indicate the motion beyond the boundary, however Unity isn’t handling these events as expected.
Here’s what I know:
-
onGenericMotionEvent does NOT get called if the mouse movement is being clamped (for example, position = 0,0 moving left/up)
-
dispatchGenericMotionEvent does get called in this situation, with the expected MotionEvent.AXIS_RELATIVE_X
-
dispatchGenericMotionEvent does NOT get called if the mouse button is down (maybe only if dispatchTouchEvent is overloaded?)
-
dispatchTouchEvent gives you the expected MotionEvent.AXIS_RELATIVE_X while the button is down.
From this, I can track my own mouse deltas to work around the unity bug, but it’s pretty hacky. Any chance we can get a fix from Unity for this bug?
1 Like
Any comment on this from Unity? Is this a known issue?
1 Like
pinging this again - would love to remove my hacky workaround - any chance this will be fixed?
Same issue, Updates solved nothing.
I think the issue is with quest and android not Unity.
No, it’s definitely a bug in how Unity implements mouse on Android (it’s default activity uses the wrong events).
I’m still waiting on a fix, but have heard nothing from unity…going on a year and a half since I reported it. In the mean time, the fix is to replace their Activity with a fixed version and use a replacement API for mouse instead of Input.XXX.
Here’s the workaround I use:
public class MouseWorkaroundActivity extends UnityPlayerActivity {
public float accumulatedDeltaX, accumulatedDeltaY;
public void ClearAccumulatedDeltas()
{
accumulatedDeltaX = accumulatedDeltaY = 0;
}
void LogEvent(MotionEvent event, String methodName)
{
Log.d("MouseWorkaroundActivity", methodName +
" - (" + event.getAxisValue(MotionEvent.AXIS_RELATIVE_X, 0) + ", "+ event.getAxisValue(MotionEvent.AXIS_RELATIVE_Y, 0) + ") " +
event.toString());
}
@Override public boolean dispatchTouchEvent(MotionEvent event)
{
LogEvent(event, "dispatchTouchEvent");
if (event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE && event.getAction() == MotionEvent.ACTION_MOVE)
{
accumulatedDeltaX += event.getAxisValue(MotionEvent.AXIS_RELATIVE_X, 0);
accumulatedDeltaY += event.getAxisValue(MotionEvent.AXIS_RELATIVE_Y, 0);
}
return super.dispatchTouchEvent(event);
}
@Override public boolean onTouchEvent(MotionEvent event)
{
LogEvent(event, "onTouchEvent");
return super.onTouchEvent(event);
}
@Override public boolean dispatchGenericMotionEvent(MotionEvent event)
{
LogEvent(event, "dispatchGenericMotionEvent");
if (event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE && event.getAction() == MotionEvent.ACTION_HOVER_MOVE)
{
accumulatedDeltaX += event.getAxisValue(MotionEvent.AXIS_RELATIVE_X, 0);
accumulatedDeltaY += event.getAxisValue(MotionEvent.AXIS_RELATIVE_Y, 0);
}
return super.dispatchGenericMotionEvent(event);
}
@Override public boolean onGenericMotionEvent(MotionEvent event)
{
LogEvent(event, "onGenericMotionEvent");
return super.onGenericMotionEvent(event);
}
}