How can I use a sprite for my hardware cursor using Cursor.SetCursor?
I want to take a game object’s image property which is a sprite for UI usage,
and send the texture of that sprite to the Cursor.SetCursor(), but it results
in a garbled cursor despite any configurations I try.
I implement this method in my CursorControl class:
// SET CURSOR
public void SetCursor(Texture2D sprite) {
Cursor.SetCursor(sprite, Vector2.zero, CursorMode.Auto);
}
This changes the hardware cursor but it makes it a corrupted and blocky image and not the sprite texture.
I suspect that this is due to the conversion between Texture2d type and Cursor type since the hardware
cursor uses Cursor type. I was able to get this method to work by making the CursorMode force software,
but that isn’t desirable due to latency and sizing issues. I would really prefer the hardware mode and to not
have to duplicate all of my game Item sprites as cursors in my project folder.
I believe the cursor uses a Texture2D but it needs to be a Texture2D that is readable and writable. All the texture calls to sprite.texture or material.texture will return textures that are read only.
I was able to make a custom cursor by doing this:
Right click in my Project tab and choose Import Asset
Navigate to a image on my computer (.png, jpg) and select it
In my Project tab highlight the new texture just imported
Select Texture Type Drop down (first one) and change from Default to Cursor
Click Advanced tab and checkMark Read/Write Enable
Select apply
Created the script shown below.
Created an Empty GameObject and dragged the script onto it.
Dragged my Texture from my project folder onto the Inspector of the script
Clicked play and had a custom cursor.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine.UI;
public class GenericTest : MonoBehaviour
{
public Texture2D cursorTexture;
private void Start()
{
Cursor.SetCursor(cursorTexture, Vector2.zero, CursorMode.Auto);
}
}
Note: you might also need to click Alpha is transparent and make sure the alpha is set correctly in the image. Additionally you’ll want to set a better hotspot than Vector2.zero (which i believe is the bottom left corner of your image).
Thank you for that answer but it doesn’t solve my problem. I set the sprite type to (Sprite and UI) and also checked
read / write but it doesn’t fix it. My problem is that I am trying to pass the Texture2d property of a Sprite as the argument
for the Cursor.SetCuror(). My goal is to use Sprites (sprite.texture) from my project folder as the hardware cursor, but
doing so doesn’t produce the desired results. I wonder if there is a problem with Unity changing the hardware cursor
because the results are garbled squares of visual information for a cursor.
I don’t understand the problem. Where did this sprite.texture come from. Just import is a texture without attaching it to a sprite? Why does it have to a be a texture from a sprite?
I am using the type Sprite for my UI images and I want to change the cursor to match the images when they are
hovered over. To do this, the Texture2d property of those sprites is being passed to Cursor.SetCursor() like this:
// SET CURSOR
public void SetCursor(Texture2D texture) {
Cursor.SetCursor(texture, Vector2.zero, CursorMode.Auto);
}
The object that the parameter is getting the texture property of the sprite from is a UI element that the mouse hovers over.
Each UI element represents a game item that has a sprite property which represents its image and is assigned a sprite from
the inspector. Athough the Cursor.SetCursor method takes a Texture2d as an argument, it only results in a garbled cursor.
I suspect there may be a bug or error in the way Unity converts the textures to cursors or that I am not implementing it
properly. I also tried setting this up with the game item’s image having a Texture2d type (instead of grabbing the texture
from a sprite) with read/write enabled in the project folder, resulting in the same garbled cursor.
It seems pretty easy to have a read/write Texture in your assets folder that is the same image you made all those sprites from. Each gameOjbect that has one of these sprites could also have a Public Texture2D setup the way i described above. and you just pass that instead of the sprite.texture. I think you could also just create a new Texture2D copy the sprite.texture into it and then make it type.Cursor and read/write. . I’ll look into how to do it programmatically. Though for sure you have a fairly easy way to implement what you want with just plain old textures.
Ok to figure out how to set a cursor from a Sprite I did the following:
Created a an Image in MSPaint of an arrow. I imported it into my Unity Projects folder.
I created a new 2D->Sprite gameObject.
It wouldn’t let me drag the Texture onto the Sprite Object in the Inspector
So I changed its drop down from Default to Sprite(2D and UI)
I then added this script to the Sprite:
using System;using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SetCursor : MonoBehaviour {
// Use this for initialization
void Start () {
SpriteRenderer rend = GetComponent<SpriteRenderer>();
Cursor.SetCursor(rend.sprite.texture, Vector2.zero, CursorMode.Auto);
}
}
Worked perfectly and created a cursor just fine (So i was wrong about the cursor messing up because sprite textures are read only).
Then to test UI… I created a UI Image (which autopopulated a canvas and EventSystem. Added this Script to my UI Image:
using System;using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class SetCursor : MonoBehaviour {
// Use this for initialization
void Start () {
Image image = GetComponent<Image>();
Cursor.SetCursor(image.sprite.texture, Vector2.zero, CursorMode.Auto);
}
}
It also produced a cursor from the image on my screen. So how are you making the sprites whose textures are messing up the cursor?
I was able to make the hardware cursor swap work by giving the game object another property of type
Texture2d to go along with it’s sprite and setting the Texture2d image to Cursor type in the project folder.
However, doing this has a couple limitations that I would like to find a way around. First, and my biggest
concern, is the bloating of my project by duplicating images in my project to accommodate having both
a sprite and a cursor texture. Second is the size limitation of the hardware cursor of 32x32 pixels. I would
like to resize my hardware cursor to display at 128x128 when the swap takes place.
When I did the above and got the cursor to change from my sprites (without the extra textures) my cursor was as big as my sprite. If I had a 300x300 sprite my cursor was 300x300 pixels big (nearly 10x the size of the original windows arrow cursor). So how are you making your sprites so we can figure out why your code won’t make the cursor from a sprite, since It seems fairly straight forward. I basically used your posted code and it worked 100%. I even changed my script to double check that passing the texture through a method wasn’t causing problems:
I created a UI image from a 600x600 sized Arrow and added this code to the UI Image:
using System;using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class SetCursor : MonoBehaviour {
// Use this for initialization
void Start () {
Image image = GetComponent<Image>();
SetMyCursor(image.sprite.texture);
}
private void SetMyCursor(Texture2D tex )
{
Cursor.SetCursor(tex, Vector2.zero, CursorMode.Auto);
}
}
What version of Unity are you using?
I am using 5.5.0f3. When I set the cursor to a Cursor texture type that is 128x128, it shows the image
on the cursor fine, but at 32x32. When I set the cursor to the Default texture type that is 128x128, it
shows the image as garbled information but at 32x32. Both were set to max size of 128. The goal is
to display the cursor in hardware mode at 128x128. I’m hoping this is a version bug and that upgrading
will fix it.
I spent SO LONG trying to figure this out! I tried several different ways, was pouring through Unity docs, Googling, until I stumbled on your comment. THANK YOU! It’s finally working how I need it to, you’re a lifesaver!