I’m writing an editor script, and in a part I’m using Event.delta to calculate movement.
The problem is, the delta will be <0,0> when cursor hit the screen edge. I’m wondering how to make the cursor to wrap around the screen edge like when dragging the handle.
I made a script that does this for Windows. Though it could be expanded to include other platforms.
In this case it has an “OnWrap” event to send messages to other parts of the code that may respond badly to making the cursor jump like that.
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.Events;
public class CursorWrap : MonoBehaviour {
[System.Serializable]
public class WrapEvent : UnityEvent<Vector2> { }
public WrapEvent OnWrap;
#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
public class Win32 {
[DllImport("User32.Dll")]
public static extern long SetCursorPos(int x, int y);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetCursorPos(out POINT lpPoint);
[StructLayout(LayoutKind.Sequential)]
public struct POINT {
public int X;
public int Y;
public POINT(int x, int y) {
this.X = x;
this.Y = y;
}
}
}
private void Update() {
Vector2 mp = Input.mousePosition;
Vector2 screen = new Vector2(Screen.width, Screen.height);
int d = 1;
int wrapHorizontal = 0;
if(mp.x <= d)
wrapHorizontal = 1;
else if(mp.x >= screen.x - d)
wrapHorizontal = -1;
int wrapVertical = 0;
if(mp.y <= d)
wrapVertical = -1;
else if(mp.y >= screen.y - d)
wrapVertical = 1;
if(wrapHorizontal != 0 || wrapVertical != 0) {
Win32.GetCursorPos(out Win32.POINT p);
Vector2 delta = new Vector2(wrapHorizontal, wrapVertical);
delta.Scale(screen - d * Vector2.one);
Win32.SetCursorPos(p.X + (int)delta.x, p.Y + (int)delta.y);
delta.Scale(new Vector2(1f, -1f));
OnWrap.Invoke(delta);
}
}
#endif
}