How can I move the mouse without moving the cursor? (Syringe Mechanic)

Hi everyone,

I have a Syringe in my game and the following behavior: The Syringe-Object follows the Mouse Position and when I click, I stop the Syringe from following the mouse and moving the mouse now presses the Plunger (which is part of / attached to the Syringe).

When I release the Mouse Button, unfortunately, the Syringe-Object makes a sudden jump because the mouse position changed.
What I want, however, is to release the mouse button and have the Syringe stay at the same position as before.

How can I prevent this jump from happening? I already researched and found out that there is no native/cross-platform way to stop the cursor from moving.

Do you guys have any suggestions on how to move about?

Thanks for reading!

Like you already know there’s no built-in (and therefore no cross platform) way to set the mouse cursor to a certain position besides the center (Cursor.lockState).

So if you need to set the mouse cursor to a certain position, you have to find a platform dependent way. For windows you have to use SetCursorPos (and maybe ClientToScreen) from the WinAPI. I don’t work with other platforms (besides Android but it doesn’t have a mouse ^^).

Of course there’s no way to implement something like that in a webbuild.

edit
To implement a virtual mouse pointer all you need is to track the mouse delta and move a Vector3 around (could be a gameobject).

// C#
public float horizontalSpeed = 10f; // looks like "10" maps to the native speed
public float verticalSpeed = 10f;

public Transform cursorObj;

public bool allowCursorMove = true;

void CheckCursorLock()
{
    if (Cursor.lockState == CursorLockMode.None)
    {
        Cursor.lockState = CursorLockMode.Locked;
        Cursor.visible = false;
    }
}

void Start()
{
    CheckCursorLock();
}

void Update()
{
    if (Input.GetMouseButtonDown(0))
    {
        CheckCursorLock();
    }
    float h = horizontalSpeed * Input.GetAxis("Mouse X");
    float v = verticalSpeed * Input.GetAxis("Mouse Y");
    Vector3 delta = new Vector3(h,v,0);
    if (allowCursorMove)
    {
        cursorObj.position += delta; // moves the virtual cursor
        // You need to clamp the position to be inside your wanted area here,
        // otherwise the cursor can go way off screen
    }
}

This script will hide the hardware mouse cursor and instead moves a gameobject around according to the mouse delta. The gameobject could be anything, even a 3D object. Of course everything that involves a mouse position should use your virtual mouse position (the position of the cursor GameObject) from now on.

That could get a bit difficult with GUI stuff, but i think with the new UI system that should be doable. Just implement your own “PointerInputModule” derived module that doesn’t use Input.mousePosition as the “StandaloneInputModule” does. Just use your virtual mouse position instead.

It’s kind of impossible to use a virtual mouse position with the old GUI system (OnGUI).

To get the cursor right you have to consider the projection to the screen. The easiest would be to display an UI element in screen coordinates.

Yes, you can !

You should hide the default cursor

Than create a virtual cursor, which is just a 2d sprite you show where you want, we will position the sprite based on the mouse position (which you can still get even if it’s hidden)

You can than clamp the “virtual cursor” to the screen.

// Use this for initialization

	public GameObject cursor;
	public Camera c;

void Start () {
		Screen.showCursor = false; 
	}
	
	// Update is called once per frame
	void Update () {
		Vector3 mousePos = Input.mousePosition;
		Vector3 pos = c.ScreenToWorldPoint(mousePos);

		cursor.transform.position = pos;
	}

Since lockstate is disabled in Unity5 try this: center cursor and toggle on and off (Unity 5) - Unity Answers