Input.mousePosition doesn't update...

I’m not sure if this is a bug or just the way Unity works. If I click outside the Game tab, Input.mousePosition stops updating until I re-click inside the Game tab again. It looks like a focus issue.

I have things in my game that can be dragged. I don’t want drag to start unless the old and new position are different. Unfortunately, if I click outside the Game tab, then move the mouse back into the Game tab, hover the mouse over an object then click, the game thinks I want to drag the object since the old position hasn’t changed since I clicked something outside of the Game tab.

Anyone else having this problem? Is there a way to force Input.mousePosition to update once the mouse is hovering over the Game tab again?

Hmm, running into exactly this issue in 2018 – any thoughts?

EDIT: To elaborate, I get a large single frame mouse delta when the game regains focus. It would be easy to reject deltas over a certain magnitude, but it feels like a hack.

public class InputManager : Singleton<InputManager> {
    private Vector2 m_mousePrev = Vector2.zero;
    private Vector2 m_mouseCurr = Vector2.zero;
    private bool m_drag = false;

    public Vector2 GetMouseDrag() {
        Vector2 delta = m_mouseCurr - m_mousePrev;
        return m_drag && delta.sqrMagnitude < 1000.0f ? delta : Vector2.zero;
    }

    void Update() {
        m_drag = Input.GetMouseButton(0);
        m_mousePrev = m_mouseCurr;
        m_mouseCurr = Input.mousePosition;
    }
}

I had encountered this same issue while trying to implement raycasting while dragging a React component over my Unity game instance window. Very easy to accomplish for the mouse, but with touches, the Input class does not register anything that originates outside of the player.

To solve this I made two private variables, a bool, and a Vector3 that I create from a csv value passed in from javascript through sendMessage.

bool SHOULD_CAST_RAY;
bool USE_EXTERNAL_ORIGINATING_TOUCH_POS;
Vector3 EXTERNAL_ORIGINATING_TOUCH_POS;

public void LateUpdate()
{
    if (SHOULD_CAST_RAY)
    {
        if (USE_EXTERNAL_ORIGINATING_TOUCH_POS && EXTERNAL_ORIGINATING_TOUCH_POS.z < 0) { return; }

        RaycastHit hit;
        Vector3 screenPoint = Input.mousePresent ? Input.mousePosition : Vector3.zero;
        Vector3 viewportPoint = USE_EXTERNAL_ORIGINATING_TOUCH_POS ? RigsCamera.ScreenToViewportPoint(EXTERNAL_ORIGINATING_TOUCH_POS) : Vector3.zero;

        if (Physics.Raycast(
            USE_EXTERNAL_ORIGINATING_TOUCH_POS
                ? RigsCamera.ViewportPointToRay(new Vector3(viewportPoint.x, 1 - viewportPoint.y, 0))
                : RigsCamera.ScreenPointToRay(screenPoint),
            out hit,
            CameraRigControllerScript.CameraDistanceMax * 1.5f,
            1 << 10
        )) {
            if (CURRENT_SELECTION == null)
            {
                CURRENT_SELECTION = UnsafeGetModelInstantiationFromRaycast(hit);
                ApplySelectionIndication();
            }
            else if (!IsAlreadySelected(hit))
            {
                RemoveSelectionIndication();
                CURRENT_SELECTION = UnsafeGetModelInstantiationFromRaycast(hit);
                ApplySelectionIndication();
            }
            return;
        }

        if (CURRENT_SELECTION != null)
        {
            RemoveSelectionIndication();
            CURRENT_SELECTION = null;
        }
    }
}

// The below methods are used to control the raycasting from React through sendMessage
public void ClearExternalOriginatingTouchPosition()
{
    EXTERNAL_ORIGINATING_TOUCH_POS = new Vector3(0, 0, -1f);
    USE_EXTERNAL_ORIGINATING_TOUCH_POS = false;
}

public void DisableRaycasting()
{
    SHOULD_CAST_RAY = false;
    RemoveSelectionIndication();
    CURRENT_SELECTION = null;
}

public void EnableRaycasting()
{
    SHOULD_CAST_RAY = true;
}

public void SetExternalOriginatingTouchPosition(string csv)
{
    string[] pos = csv.Split(',');
    EXTERNAL_ORIGINATING_TOUCH_POS = new Vector3(float.Parse(pos[0]), float.Parse(pos[1]), 0);
    USE_EXTERNAL_ORIGINATING_TOUCH_POS = true;
}

I hope this information helps some people! If anyone has questions or needs more information, please feel free to ask.