Search Unity

Hardware Cursor Support

Discussion in 'Scripting' started by Games-Foundry, May 19, 2011.

  1. Games-Foundry

    Games-Foundry

    Joined:
    May 19, 2011
    Posts:
    632
    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):
    1.  
    2. using UnityEngine;
    3. using System;
    4. using System.Collections;
    5. using System.Runtime.InteropServices;
    6.  
    7. public class CursorManager : MonoBehaviour
    8. {
    9.     [DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
    10.     public static extern IntPtr SetCursor(IntPtr hCursor);
    11.    
    12.     [DllImport("user32.dll")]
    13.     public static extern IntPtr LoadCursor(IntPtr hInstance, int lpCursorName);
    14.    
    15.     [DllImport("user32.dll")]
    16.     public static extern IntPtr LoadImage(IntPtr hInstance, string lpImageName, uint uType, int cxDesired, int cyDesired, uint fuLoad);
    17.  
    18.     //fuLoad
    19.     public const uint LR_CREATEDIBSECTION     =0x00002000;
    20.     public const uint LR_DEFAULTCOLOR     =0x00000000;
    21.     public const uint LR_DEFAULTSIZE     =0x00000040;
    22.     public const uint LR_LOADFROMFILE     =0x00000010;
    23.     public const uint LR_LOADMAP3DCOLORS     =0x00001000;
    24.     public const uint LR_LOADTRANSPARENT     =0x00000020;
    25.     public const uint LR_MONOCHROME     =0x00000001;
    26.     public const uint LR_SHARED     =0x00008000;
    27.     public const uint LR_VGACOLOR     =0x00000080;
    28.    
    29.     public void ChangeCursorToArrow()
    30.     {
    31.         SetCursor(LoadCursor(IntPtr.Zero, 32512));
    32.     }
    33.    
    34.     public void ChangeCursorToCustom(string filePath)
    35.     {
    36.         SetCursor(LoadImage(IntPtr.Zero, filePath, 2, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE));
    37.     }
    38.    
    39.     public void Init()
    40.     {
    41.         string cursorPath = Application.dataPath+"/Resources/Cursors/normal.cur";
    42.         ChangeCursorToCustom(cursorPath);
    43.     }
    44. }
    45.  
     
    Last edited: May 19, 2011
  2. Games-Foundry

    Games-Foundry

    Joined:
    May 19, 2011
    Posts:
    632
    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.
     
  3. MattijsKneppers

    MattijsKneppers

    Joined:
    Jun 30, 2014
    Posts:
    15
    When searching for a way to load another standard cursor already included n the OS, I ended up with this:

    Code (CSharp):
    1.  
    2.       public enum WindowsCursor
    3.         {
    4.             StandardArrowAndSmallHourglass = 32650,
    5.             StandardArrow = 32512,
    6.             Crosshair = 32515,
    7.             Hand = 32649,
    8.             ArrowAndQuestionMark = 32651,
    9.             IBeam = 32513,
    10.             //Icon = 32641, // Obsolete for applications marked version 4.0 or later.
    11.             SlashedCircle = 32648,
    12.             //Size = 32640,  // Obsolete for applications marked version 4.0 or later. Use FourPointedArrowPointingNorthSouthEastAndWest
    13.             FourPointedArrowPointingNorthSouthEastAndWest = 32646,
    14.             DoublePointedArrowPointingNortheastAndSouthwest = 32643,
    15.             DoublePointedArrowPointingNorthAndSouth = 32645,
    16.             DoublePointedArrowPointingNorthwestAndSoutheast = 32642,
    17.             DoublePointedArrowPointingWestAndEast = 32644,
    18.             VerticalArrow = 32516,
    19.             Hourglass = 32514
    20.         }
    21.    
    22.         private static void ChangeCursor(WindowsCursor cursor){
    23.             SetCursor(LoadCursor(IntPtr.Zero , (int)cursor));
    24.         }
    25.    
    26.         [DllImport("user32.dll", EntryPoint = "SetCursor")]
    27.         public static extern IntPtr SetCursor(IntPtr hCursor);
    28.    
    29.         [DllImport("user32.dll", EntryPoint = "LoadCursor")]
    30.         public static extern IntPtr LoadCursor(IntPtr hInstance, int lpCursorName);
    31.