Changer la position de la souris par code dans l’éditeur

Dans certains outils, il est souvent utile de replacer la souris à un endroit précis. Ce court article montre comment déplacer le curseur de la souris Windows depuis l’éditeur (éditeur uniquement, et Windows uniquement).
Vous pouvez :
- sauvegarder la position de la souris,
- déplacer la souris à une position x ; y donnée,
- ramener la souris à la position sauvegardée.
Démonstration

Un cas d’usage : quand on clique sur le bouton « Delete », on sauvegarde la position actuelle de la souris et on affiche une popup. Quand la popup se ferme, on ramène la souris à la position sauvegardée.
Utilisation
- Ça ne fonctionne que sous Windows. Sur Mac ou Linux, vous trouverez sûrement l’équivalent en ligne.
- Placez les scripts ci-dessous dans n’importe quel dossier
Editor/. - J’utilise une
EditorWindowpour montrer l’exemple : ouvrez-la depuis Window/SampleEditorWindow, comme sur l’image. Vous pouvez changer ce chemin de menu dans le scriptSampleEditorWindow.cs, juste avant la fonctionInit().
Scripts
Win32Mouse.cs
Win32Mouse.cs
/// <summary>
/// MIT License - Copyright(c) 2019 Ugo Belfiore
/// </summary>
#if UNITY_STANDALONE_WIN || UNITY_EDITOR
using System.Runtime.InteropServices;
using UnityEngine;
namespace MoveMouseEditor
{
public static class Win32Mouse
{
[DllImport("User32.Dll")]
private static extern long SetCursorPos(int x, int y);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetCursorPos(out POINT lpPoint);
private static Vector2 _lastPosition;
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int X;
public int Y;
public POINT(int x, int y)
{
this.X = x;
this.Y = y;
}
}
/// <summary>
/// change the mouse position in window
/// </summary>
/// <param name="positon">wanted position</param>
public static void SetCursorPosition(Vector2 positon)
{
SetCursorPosition((int)positon.x, (int)positon.y);
}
/// <summary>
/// change the mouse position in window
/// </summary>
/// <param name="x">wanted position x</param>
/// <param name="y">wanted position y</param>
public static void SetCursorPosition(int x, int y)
{
Win32Mouse.SetCursorPos(x, y);
}
/// <summary>
/// change the mouse position with the previously saved position.
/// If you did'nt saved the mouse position, set the mouse cursor
/// to 0,0
/// </summary>
public static void LoadPreviouslySavedPosition()
{
Win32Mouse.SetCursorPosition(Win32Mouse.GetLastSavedPosition());
}
/// <summary>
/// save the mouse position
/// </summary>
public static void SavePosition()
{
_lastPosition = GetCursorPosition();
}
/// <summary>
/// return the last saved position
/// </summary>
/// <returns></returns>
public static Vector2 GetLastSavedPosition()
{
return (_lastPosition);
}
/// <summary>
/// add an offset to the current mouse position
/// </summary>
/// <param name="offset">offset to apply</param>
public static void AddToMousePosition(Vector2 offset)
{
Vector2 currentPosition = Win32Mouse.GetCursorPosition();
Win32Mouse.SetCursorPosition(currentPosition + offset);
}
/// <summary>
/// return the current mouse position X,Y
/// </summary>
/// <returns>mouse position</returns>
public static Vector2 GetCursorPosition()
{
POINT newPoint;
Win32Mouse.GetCursorPos(out newPoint);
return (new Vector2(newPoint.X, newPoint.Y));
}
}
}
#endif
SampleEditorWindow.cs
SampleEditorWindow.cs
/// <summary>
/// MIT License - Copyright(c) 2019 Ugo Belfiore
/// </summary>
using UnityEditor;
using UnityEngine;
namespace MoveMouseEditor
{
/// <summary>
/// exemple of an EditorWindow
/// </summary>
public class SampleEditorWindow : EditorWindow
{
[MenuItem("Window/SampleEditorWindow")]
static void Init()
{
SampleEditorWindow window = (SampleEditorWindow)EditorWindow.GetWindow(typeof(SampleEditorWindow));
window.Show();
}
/// <summary>
/// display all the GUI inside the editorWindow
/// </summary>
private void OnGUI()
{
DisplayButtons();
}
/// <summary>
/// display the core of the editorWindow
/// </summary>
private void DisplayButtons()
{
DisplaySaveButton();
GUILayout.Label("");
DisplayLoadButton();
GUILayout.Label("");
GUILayout.Label("");
DisplayDeleteButton();
}
/// <summary>
/// display save button & execute the saving position if button pressed
/// </summary>
private void DisplaySaveButton()
{
if (GUILayout.Button("Save Mouse Position"))
{
Win32Mouse.SavePosition();
Debug.Log("mouse position saved !");
}
}
/// <summary>
/// display load button & execute the loading position if button pressed
/// </summary>
private void DisplayLoadButton()
{
if (GUILayout.Button("Load previously saved position"))
{
Win32Mouse.LoadPreviouslySavedPosition();
Debug.Log("mouse moved to the previously saved position !");
}
}
/// <summary>
/// display delete button & open the popup if button pressed
/// </summary>
private void DisplayDeleteButton()
{
GUI.backgroundColor = Color.red;
if (GUILayout.Button("Delete button"))
{
if (!ExtGUI.DrawDisplayDialog(mainTitle: "delete", content: "Are you sure you want to delete ?"))
{
return;
}
Debug.Log("content deleted !");
}
GUI.backgroundColor = Color.white;
}
}
}
ExtGUI.cs
ExtGUI.cs
/// <summary>
/// MIT License - Copyright(c) 2019 Ugo Belfiore
/// </summary>
using UnityEditor;
namespace MoveMouseEditor
{
/// <summary>
/// Display a Dialog Box. Return true if the user press YES
/// return false if the user press CANCEL, or press exit
///
/// if replaceMousePositionAtTheEnd is true, move the mouse position
/// to it's original emplacement before the dialog show up.
/// </summary>
public static class ExtGUI
{
public static bool DrawDisplayDialog(
string mainTitle = "main title",
string content = "what's the dialog box say",
string accept = "Yes",
string no = "Get me out of here",
bool replaceMousePositionAtTheEnd = true)
{
if (replaceMousePositionAtTheEnd)
{
Win32Mouse.SavePosition();
}
if (!EditorUtility.DisplayDialog(mainTitle, content, accept, no))
{
if (replaceMousePositionAtTheEnd)
{
Win32Mouse.SetCursorPosition(Win32Mouse.GetLastSavedPosition());
}
return (false);
}
if (replaceMousePositionAtTheEnd)
{
Win32Mouse.SetCursorPosition(Win32Mouse.GetLastSavedPosition());
}
return (true);
}
}
}
Fichiers source
Voir aussi
- Changer la projection de la caméra : passer la caméra de la perspective à l’orthographique par interpolation linéaire couplée à une fonction d’easing.
- Chronos et cooldowns : pour tous vos timers et cooldowns dans Unity. Fini les
Invoke(), les coroutines ou les vérifications de temps à la main dansUpdate(). - Time, TimeScale et DeltaTime dans l’éditeur : une classe
TimeEditorqui reproduit le comportement de la classeTimeen mode édition. Utile pour les outils qui ont besoin de timers et de ralentis.



