1. Vote on the next Unite Training Day project genre here
  2. VS Code Unity debugger extension preview

Hardware Cursor Support

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

  1. Games Foundry

    Games Foundry

    May 19, 2011
    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:

    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):
    2. using UnityEngine;
    3. using System;
    4. using System.Collections;
    5. using System.Runtime.InteropServices;
    7. public class CursorManager : MonoBehaviour
    8. {
    9.     [DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
    10.     public static extern IntPtr SetCursor(IntPtr hCursor);
    12.     [DllImport("user32.dll")]
    13.     public static extern IntPtr LoadCursor(IntPtr hInstance, int lpCursorName);
    15.     [DllImport("user32.dll")]
    16.     public static extern IntPtr LoadImage(IntPtr hInstance, string lpImageName, uint uType, int cxDesired, int cyDesired, uint fuLoad);
    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;
    29.     public void ChangeCursorToArrow()
    30.     {
    31.         SetCursor(LoadCursor(IntPtr.Zero, 32512));
    32.     }
    34.     public void ChangeCursorToCustom(string filePath)
    35.     {
    36.         SetCursor(LoadImage(IntPtr.Zero, filePath, 2, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE));
    37.     }
    39.     public void Init()
    40.     {
    41.         string cursorPath = Application.dataPath+"/Resources/Cursors/normal.cur";
    42.         ChangeCursorToCustom(cursorPath);
    43.     }
    44. }
    Last edited: May 19, 2011
  2. Games Foundry

    Games Foundry

    May 19, 2011
    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.