I needed to have custom hardware cursos in my PC/MAC game, due to low FPS on slow machines. I found no solution, so I've written this very simple plugin. It enables custom hardware cursor support in Unity standalone applications for PC/MAC.
All you have to do is download the package, and follow the tutorial provided in PDF.
The plugin requires Unity Pro. Minimum Unity version is 3.0.
Drop me a line if you find it useful, or in case you had problems or questions.
Last edited by calveit; 03-09-2011 at 01:45 AM. Reason: Source for dll/bundle attached.
Oh man I've wanted this for a while! Never had the Cocoa/Carbon/MFC or whatever knowledge to attempt it, though. I'll put it in our project now and let you know how it goes.
Can you recommend a .cur editor for Mac OS? The cursor editing market seems to be mostly malware and crapware.
Ok, so I think I've followed your instructions:
- I added CP 0.1.unitypackage to my project
- I put a cursor file at Resources/Cursors/aero_unavail.cur
- I added the following script to an object in the first scene:
Aside from the debug statement, I can see no change in my build. The standard Mac OS cursor is there from the beginning. No errors or anything.Code:
This is an Intel-only build on Mac OS X 10.6.5. What might I be doing wrong?
Thanks for trying the plugin, and your feedback!
I guess there's a bug in the document, which says cursors are copied to Application.dataPath / Cursors, but in fact the path should be: Application.dataPath/. Please try the same code with the path:
Last edited by calveit; 12-10-2010 at 01:53 AM. Reason: Formatting
Oops, that was my mistake. I just put my cursor in Resources/Cursors for organizational purposes. I didn't realize that the directory would be flattened in the build.
However, now that I've confirmed that the logged path and the path to the cursor in the build are the same, it still doesn't seem to do anything. Any ideas?
Ok, I think I understand what was happening. I had forgotten that the contents of Resources is not just copied into the build: only assets in that directory are copied automatically. Your PostprocessBuildPlayer scripts copy the cursor files, and they expect to find the cursors in Resources/Cursors. I must have messed something up the time I thought I was doing it properly.
In any case, it seems to work fine if you do exactly as you say:
- Put the cursor files in Assets/Resources/Cursors
- Load files from Application.dataPath + "/" + cursorNameIncludingExtension
The only problem I've found so far is that under Mac OS, the cursor reverts to the system cursor when you click on the menu bar.
What's the benefit of using this as opposed to hiding the cursor and using an in-game asset?
Cameron, if you use this you don't have to rely on your game's FPS in matter of displaying the cursor. In other words, if your game runs smoothly (ie. at 60 FPS), there's no need to use this plugin. But if the FPS drops below 20 - 25 FPS, you will notice that your cursor starts to float and does not update its position instantly. That's because it depends on your Update call frequency. This plugin delegates cursor handling to the OS, so it does not depend on your FPS.
The problem in most cases is: why does your game run so slowly? But there are situations in which you are obliged to support very old machines, or where FPS does not impact the rest of the gameplay (ie. Hidden Object / Puzzle games).
Daniel, I will look into the problem you've found and post a soulution as soon as I manage to fix it.
Thanks for that explanation Calveit, makes perfect sense now!
I think I've fixed this issue. New version (0.2) is available as attachment to the first post of this thread.
You do not need to to change your code, only switch OS X library (.bundle) to new version.
Hey, thanks for this contribution.
However, the doc/pdf need to be corrected: the call to CursorPlugin.InitializeCursor & CursorPlugin.SetCurrentCursor should be:
Even so, I didn't manage to make it to work.
I have a cur file in Resources/Cursors and I have a GO in my scene with a .cs script like this:
I Build and Run and see nothing...
What could be wrong?
Last edited by immFX; 12-22-2010 at 06:04 AM.
Thanks for your feedback immFX!
You're right, I will correct the tutorial document.
Your script seems ok and the plugin should work. Could you provide some more details on your situation? What OS you're running? Has Postprocess script copied the .cur files to the Application.dataPath of your build folder?
Also, have you tried to build sample project?
I just had a chance to test the new version on a Mac. It definitely behaves better when in windowed mode (going to the system cursor when the cursor leaves the game window is a good idea), but it seems to have problems with fullscreen:
1. Switching to or from fullscreen changes the cursor back to the system default. It will be changed again when SetCurrentCursor() is called.
2. If you switch from fullscreen to windowed mode (windowed>fullscreen>windowed or fullscreen>windowed and then call SetCurrentCursor(), the behaviour reverts back to what I saw in version 1: the cursor switches properly, but does not change at the edges of the window. However, clicking on a menu item will cause the cursor to switch back to the system cursor.
3. Finally, if the game starts in fullscreen then no cursor changes will be respected at all until you switch back to windowed mode.
If you can fix 2. and 3. then I can work around 1.
Thanks for your continued work!
I've tested this plugin further, and on Windows XP I'm getting a DllNotFoundException. It provides the path where it is looking, and I double-checked it to make sure it is correct. Apparently this can happen if the plugin has a dependency that cannot be satisfied. The plugin works fine on Windows Vista and 7.
Having looked further into this issue, I might be able to give you more specific information after trying Dependency Walker. I'll do that sometime soon.
Thanks, Calveit, very nice start!
I wonder, is there possibility for some Generic GUI class, which will detect when mouse cursor is over some button? Will try looking into it right now.