UIElements style.cursor in code

I tried searching the forums, the docs, and the internet to no avail.

How do I set the cursor style for a VisualElement to one of the predefined classes in code? (Arrow, Text, Split Resize Left Down, etc)

I am aware the cursor can be set using style.cursor = SomeCursorStyle;
The problem is I want to use the SplitResizeLeftRight cursor and I can’t seem to find where the static classes are defined. Obviously I can do this though a stylesheet, but I want to do it through code.


Well, I figured it out. For anyone else who ever runs into this issue:

style.cursor = UIElementsEditorUtility.CreateDefaultCursorStyle(MouseCursor.ResizeHorizontal)

Damn… it’s internal… and it’s gone in 2019.3…

1 Like

What I ended up doing was to create a style class in USS for each cursor I needed. Then I would call AddToClassList/RemoveFromClassList to set the desired cursor.

Using USS styles is the recommended approach for assigning default cursors. Most cases of default cursors are while hovering anyway, which uses the :hover pseudo state, and pseudo states are equally not accessible in C#.

2 Likes

I feel like this should be accessible through the C# API. It’d be handy if both USS and C# functionality matched

13 Likes

help… unity 2020 how work in csharp

Hi, I am a bit lost with this in Unity 2021.3. When I set a cursor via USS, all I can specify in UIBuilder is a texture. How do I change its size and hotspot? Or how do I specify a standard cursor type like “resize horizontal”?

3 Likes

Bumping this - anyone?

2 Likes

This still seems to be a relevant issue since 2019. For example, I can’t define Unity’s built-in cursors in UIBuilder even with Editor Extensions Authoring enabled. So it seems the USS is the only way to achieve that,

I don’t know if this was valid back in 2019 when this quote was written, or if I misinterpreted it, but in CSS, for example, and probably USS too, if you set the cursor to the element, it becomes the cursor for the element when hovering. In other words, there is no need for pseudo states nor they are relevant in this scenario.

I found when i was looking for an answer and here is how you can change cursor via code:

I’ve created a button in c#. Like that:

      Button reimportMaterialsButton = new Button();
      reimportMaterialsButton.name = "reimportMatButton";

And i’ve added this class to the my uss file:

#reimportMatButton {
    min-width: 100;
    flex-grow : 1;
    cursor: link;
}

To detailed answer, you can check out this documentation:

1 Like

Sure it works, but it is via USS, not via code. Instead of setting the name of the element, which is useful for other purposes, I suggest you add a class:

reimportMaterialsButton.AddToClassList("cursor-link");

In your USS you would do:

.cursor-link{
  cursor: link;
}

So you isolate the cursor for elements that use it, without affecting any other aspect of the element.

It still have some problems, like how you will attach the USS to the element or the root, but it’s an acceptable workaround.

1 Like

For those really want to do this.

public static class UnityDefaultCursor{
        public enum CursorType
        {
            Arrow = 0,
            Text = 1,
            ResizeVertical = 2,
            ResizeHorizontal = 3, 
            //....
// you can check this from ui debugger, so if u dont know what im saying then dont use this solution..
        }

        private static PropertyInfo _defaultCursorId;

        private static PropertyInfo DefaultCursorId
        {
            get
            {
                if (_defaultCursorId != null) return _defaultCursorId;
                _defaultCursorId = typeof(Cursor).GetProperty("defaultCursorId", BindingFlags.NonPublic | BindingFlags.Instance);
                return _defaultCursorId;
            }
        }

        public static Cursor DefaultCursor(CursorType cursorType)
        {
            var ret = (object) new Cursor();
            DefaultCursorId.SetValue(ret, (int) cursorType);
            return (Cursor) ret;
        }
}

Usage:

style.cursor = UnityDefaultCursor.DefaultCursor(UnityDefaultCursor.CursorType.ResizeHorizontal);

:thinking: :thinking: :thinking: Still don’t understand why there is not an exposed API.

3 Likes

Thank you, I took the liberty of adding all the cursor types:

using System.Reflection;
using UnityEngine.UIElements;

namespace YourNameSpace
{
    /// <summary>
    /// Settings the cursor via code. Thanks to:
    /// https://discussions.unity.com/t/uielements-style-cursor-in-code/762774/13
    /// <br />
    /// Usage: style.cursor = UnityDefaultCursor.DefaultCursor(UnityDefaultCursor.CursorType.ResizeHorizontal);
    /// </summary>
    public static class UnityDefaultCursor
    {
        public enum CursorType
        {
            Arrow = 0,
            Text = 1,
            ResizeVertical = 2,
            ResizeHorizontal = 3,
            Link = 4,
            SlideArrow = 5,
            ResizeUpRight = 6,
            ResizeUpLeft = 7,
            MoveArrow = 8,
            RotateArrow = 9,
            ScaleArrow = 10,
            ArrowPlus = 11,
            ArrowMinus = 12,
            Pan = 13,
            Orbit = 14,
            Zoom = 15,
            FPS = 16,
            CustomCursor = 17,
            SplitResizeUpDown = 18,
            SplitResizeLeftRight = 19
        }

        private static PropertyInfo _defaultCursorId;

        private static PropertyInfo DefaultCursorId
        {
            get
            {
                if (_defaultCursorId != null)
                    return _defaultCursorId;

                _defaultCursorId = typeof(Cursor).GetProperty("defaultCursorId", BindingFlags.NonPublic | BindingFlags.Instance);

                return _defaultCursorId;
            }
        }

        public static Cursor DefaultCursor(CursorType cursorType)
        {
            var ret = (object)new Cursor();
            DefaultCursorId.SetValue(ret, (int)cursorType);
            return (Cursor)ret;
        }
    }
}
2 Likes

This should be build in. I really dislike working with these USS files.