Well, I've passed 100 hours of evaluating Unity3D Pro. Many headaches like no included A*Pathfinding and an inability to make Terrain rotations. I've got over those hurdles. Now I'm trying to implement a custom hardware cursor. I'm working on an RTS game, where the state of the cursor is used to communicate quite a lot of visual clues to the player. Using a software cursor is NOT ACCEPTABLE, any lag with the cursor will kill the gaming experience, as documented elsewhere on this forum. So far my exhaustive searches have lead to: http://forum.unity3d.com/threads/70163-Hardware-Cursor-Plugin/page2?highlight=custom+cursor http://msdn.microsoft.com/en-us/library/ms648045(v=vs.85).aspx http://blog.naver.com/PostView.nhn?blogId=sdragoon&logNo=150096564973 and I've finally come up with the following script based on the three Windows-only solutions I can find through Google. When I run the game (within the Editor), the custom mouse pointer appears, but then vanishes when the 3D scene appears, resetting to the default windows cursor. I read somewhere that the solution only worked on .exe builds, so I ran a build and the cursor doesn't show at all in that. (Windows 7 64-bit). Is there anyone that has a solution they wouldn't mind sharing? Code (csharp): using UnityEngine; using System; using System.Collections; using System.Runtime.InteropServices; public class CursorManager : MonoBehaviour { [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); //fuLoad public const uint LR_CREATEDIBSECTION =0x00002000; public const uint LR_DEFAULTCOLOR =0x00000000; public const uint LR_DEFAULTSIZE =0x00000040; public const uint LR_LOADFROMFILE =0x00000010; public const uint LR_LOADMAP3DCOLORS =0x00001000; public const uint LR_LOADTRANSPARENT =0x00000020; public const uint LR_MONOCHROME =0x00000001; public const uint LR_SHARED =0x00008000; public const uint LR_VGACOLOR =0x00000080; public void ChangeCursorToArrow() { SetCursor(LoadCursor(IntPtr.Zero, 32512)); } public void ChangeCursorToCustom(string filePath) { SetCursor(LoadImage(IntPtr.Zero, filePath, 2, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE)); } public void Init() { string cursorPath = Application.dataPath+"/Resources/Cursors/normal.cur"; ChangeCursorToCustom(cursorPath); } }
Well, looks like it's the Unity GUI system that is resetting the cursor. Anyhows, I've managed to get lubo3d's solution working for now, as I have no C++ experience. Please Unity Team, sort this out in the main API ASAP so it also works when playing in the Editor. I nearly threw in the towel during my eval because of this.
When searching for a way to load another standard cursor already included n the OS, I ended up with this: Code (CSharp): 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);