- Home /
How do I change the hardware cursor?
I know how to use UnityGUI and DrawTexture to draw a cursor at Input.mousePosition, but it lags behind the real cursor too much when the framerate gets low. How can I change the hardware cursor (the one that is rendered independently of the memory allocated to the program)? On windows I would use the System.Windows.Input.Mouse.SetCursor() method, but I don't think this works in Unity (it uses Windows libraries).
Answer by Eric5h5 · Jul 26, 2010 at 06:47 AM
You can't change the hardware cursor in Unity.
Edit: in Unity 3, that is. You can in Unity 4.
This is true. However, there may be more options, perhaps within the $$anonymous$$ono framework.
You can use Cursor.SetCursor(). See my answer below and the documentation here.
Answer by MattijsKneppers · Apr 16, 2019 at 08:00 AM
In case you landed here trying to change the cursor to another standard/native cursor, so not a custom texture but one available in the OS by default, here is what I ended up doing (Windows only!):
public enum WindowsCursor
{
StandardArrowAndSmallHourglass = 32650,
StandardArrow = 32512,
Crosshair = 32515,
Hand = 32649,
ArrowAndQuestionMark = 32651,
IBeam = 32513,
//Icon = 32641, // Obsolete for applications marked version 4.0 or later.
SlashedCircle = 32648,
//Size = 32640, // Obsolete for applications marked version 4.0 or later. Use FourPointedArrowPointingNorthSouthEastAndWest
FourPointedArrowPointingNorthSouthEastAndWest = 32646,
DoublePointedArrowPointingNortheastAndSouthwest = 32643,
DoublePointedArrowPointingNorthAndSouth = 32645,
DoublePointedArrowPointingNorthwestAndSoutheast = 32642,
DoublePointedArrowPointingWestAndEast = 32644,
VerticalArrow = 32516,
Hourglass = 32514
}
private static void ChangeCursor(WindowsCursor cursor){
SetCursor(LoadCursor(IntPtr.Zero , (int)cursor));
}
[DllImport("user32.dll", EntryPoint = "SetCursor")]
public static extern IntPtr SetCursor(IntPtr hCursor);
[DllImport("user32.dll", EntryPoint = "LoadCursor")]
public static extern IntPtr LoadCursor(IntPtr hInstance, int lpCursorName);
At first I was like "Wtf, 9 year old question" but this is pretty useful
Yes, true, but keep in $$anonymous$$d that this only works for windows builds. When you upvote this answer you should also upvote the answer by "No_Username_Found" as this answer is actually crossplatform.
I added an extra callout that this only works on Windows.
Note though that my answer covers a different issue than the one addressed by No_Username_Found: I needed to use an anternative STANDARD windows cursor, not a Texture2D. The reason I posted here is that I expect people to end up at this thread when searching for the specific issue I was dealing with.
Answer by Senhor de todo o Mal · Oct 20, 2010 at 12:32 PM
If its for a Windows build you can try using user32.dll:
</p> <pre><code>[DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)] public static extern IntPtr SetCursor(IntPtr hCursor); [DllImport("user32.dll")] public static extern IntPtr LoadCursor(IntPtr hInstance, int lpCursorName); [DllImport("user32.dll")] public static extern IntPtr LoadImage( IntPtr hInstance, string lpImageName, uint uType, int cxDesired, int cyDesired, uint fuLoad ); </code></pre> <p>
And write some methods that you can call from your scripts:
</p> <pre><code>public static void changeCursorToHand(){ SetCursor(LoadCursor(IntPtr.Zero ,32649)); } public static void changeCursorToArrow(){ SetCursor(LoadCursor(IntPtr.Zero ,32512)); } </code></pre> <p>
This looks valid... But how do we do platform-based compile-time instructions? I remember a few weeks ago hearing that Unity 3 would have the ability for it. $compilerinstructions didn't work in the last C# implementation Unity used, and I'm not sure if that's been fixed yet.
Anyone know a mac solution, too?
http://unity3d.com/support/documentation/$$anonymous$$anual/Platform%20Dependent%20Compilation.html - Check this link for platform dependent compilation. I don't know of a mac solution, it's probably something similar, but using the equivalent to user32.dll
@Senhordetodoo$$anonymous$$al do you know if there is an alternative to your great example for unity free version? Apparently DllImport is a pro only feature :/
I know this is an old post but still the problem persists and yours is I think the only solution that works without any external 3rd party dlls. The problem is that with my current version of Unity (3.5.5) the cursor changes back to the original whenever I move the mouse. Am I doing something wrong? Do you know if unity is the problem and if so any workarounds. Thanks a lot!
A good "workaround" is to use Unity 4, which has native support for hardware cursors.
Answer by No_Username_Found · Aug 02, 2014 at 01:26 AM
Though this question is old, perhaps this answer will help someone else.
The simplest way to do this is to have a Texture2D replace the default OS cursor. This is not a Pro-Only feature and is not limited to Windows only. This is the code I used:
public Texture2D customCursor;
private CursorMode cursorMode;
private Vector2 hotSpot;
// Use this for initialization
void Start () {
//change the cursor texture
cursorMode = CursorMode.ForceSoftware;
hotSpot = new Vector2 (0, 0);
Cursor.SetCursor (customCursor, hotSpot, cursorMode);
}
Please be aware that when you are testing this, you will have to BUILD AND RUN your project to see it work. It will not change the cursor if you just press the play button in Unity.
There is more documentation available here if you want to see about having the cursor change as you mouse over other objects.
Answer by qJake · Jul 26, 2010 at 05:46 AM
If the cursor is lagging, the rest of your game must be, too (that, or your mouse cursor code is inefficient - maybe you should post it here). The only way I've discovered of drawing a cursor is via UnityGUI (of course there are more inefficient ways then UnityGUI, but none more efficient, as far as I can tell).
The game runs at ~40fps at full graphics, and the GUI code uses <6%, according to the profiler. It's just a little bit of lag, but that lag gets really annoying. It's an $$anonymous$$$$anonymous$$O, and as the number of users increases the lag does, too, which makes it even worse.