Virtual Mouse not working properly with CursorLockMode.Locked

1.Reproduce CursorLockMode.Confined on WebGL.
2.(optional) Control virtual mouse cursor with gamepad.
3.(optional) Move the in-game monitor cursor with a physical mouse.
I would like to realize these.

using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.LowLevel;
using UnityEngine.InputSystem.Users;

public class VirtualCursorTest : MonoBehaviour
{
    [SerializeField] private PlayerInput playerInput;
    [SerializeField] private RectTransform cursorTransform;
    [SerializeField] private Canvas canvas;
    [SerializeField] private RectTransform canvasRectTransform;
    [SerializeField] private float cursorSpeed = 100f;

    private bool previousMouseState;
    private Mouse virtualMouse;
    private Mouse currentMouse;
    private Camera mainCamera;

    private void OnEnable ()
    {
        mainCamera = Camera.main;
        currentMouse = Mouse.current;

        Cursor.lockState = CursorLockMode.Locked;
        Cursor.visible = false;
      
        InputDevice virtualMouseInputDevice = InputSystem.AddDevice("VirtualMouse");
        if (virtualMouseInputDevice == null) {
            virtualMouse = (Mouse)InputSystem.AddDevice("VirtualMouse");
        }
        else if (!virtualMouseInputDevice.added) {
            virtualMouse = (Mouse)InputSystem.AddDevice("VirtualMouse");
        }
        else {
            virtualMouse = (Mouse)virtualMouseInputDevice;
        }

        InputUser.PerformPairingWithDevice(virtualMouse, playerInput.user);

        if (cursorTransform != null) {
            Vector2 position = cursorTransform.anchoredPosition;
            InputState.Change(virtualMouse.position, position);
        }

        InputSystem.onAfterUpdate += UpdateMotion;
    }

    private void OnDisable ()
    {
        if (virtualMouse != null && virtualMouse.added) InputSystem.RemoveDevice(virtualMouse);
        InputSystem.onAfterUpdate -= UpdateMotion;
    }

    private void UpdateMotion ()
    {
        if (virtualMouse == null || Gamepad.current == null) return;

        Vector2 deltaValue = currentMouse.delta.ReadValue();

        Vector2 currentPosition = virtualMouse.position.ReadValue();
        Vector2 newPosition = currentPosition + deltaValue;

        newPosition.x = Mathf.Clamp(newPosition.x, 0, Screen.width);
        newPosition.y = Mathf.Clamp(newPosition.y, 0, Screen.height);

        InputState.Change(virtualMouse.position, newPosition);
        InputState.Change(virtualMouse.delta, deltaValue);

        bool aButtonIsPressed = Mouse.current.leftButton.IsPressed();
        if (previousMouseState != Mouse.current.leftButton.isPressed) {
            virtualMouse.CopyState<MouseState>(out var mouseState);
            mouseState.WithButton(MouseButton.Left, aButtonIsPressed);
            InputState.Change(virtualMouse, mouseState);
            previousMouseState = aButtonIsPressed;
        }

        AnchorCursor(newPosition);
    }

    private void AnchorCursor (Vector2 position)
    {
        Vector2 anchoredPosition;
        RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRectTransform, position, canvas.renderMode == RenderMode.ScreenSpaceOverlay ? null : mainCamera, out anchoredPosition);
        cursorTransform.anchoredPosition = anchoredPosition;
    }
}

With this script, I put the mouse cursor in the CursorLockMode.Locked state, operated the virtual mouse with the delta value of the physical mouse, and reflected it in the GUI.

However, when CursorLockMode.None, both cursor movement and button operation can be performed normally, but when CursorLockMode.Locked, the button does not respond even if the cursor can be moved.


anybewitchedkob

When InputSystemUIInputModule.cursorLockBehavior is set to ScreenCenter, even if the cursor is off the center button, it can be highlighted or clicked, so this part is probably overriding the position.

Is there any good way to solve this problem?

Unity 2021.3.9f1
Input System 1.4.3

I’m not very good at English and I use online translators a lot, so I’m sorry if my sentences sound weird.

Having this exact issue as well.

Even if there isn’t a control scheme with a 'Mouse" defined at all, the VirtualMouse will not correctly interact with UI elements if Cursor.lockState is set to CursorLockMode.Locked. It will treat the VirtualMouse position as also being locked in the center of the screen.

Sorry for the spam, I’m crystallizing some thoughts around this - I think in general what doesn’t work (but should) is having a single virtual mouse that can be controlled by either a controller, or the system mouse. Swapping input source as either device is used. It kind of works, but as mentioned there’s weird behavior surrounding Cursor.lockState affecting the interactions of the VirtualMouse.

Because ideally for this scenario we as devs would have a single “mouse” (the VirtualMouse) to concern ourselves with, letting the input system decide whether it’s controlled by a joystick or the delta of the system mouse. I want the system/native mouse to be almost completely ignored, only used to control the movement and input actions of the VirtualMouse. The hardware pointer (if present) should be hidden and locked.

This is an issue I am now running into. Cursor.lockState is indeed the issue.
A toggle in the input system settings to get around this behavior would be ideal.

Edit: Setting Cursor.lockState to “confined” works.