Way to Change what cursor looks like in game via GDScript?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By The_Duskitty
:warning: Old Version Published before Godot 3 was released.

Basically Just trying to figure out how i can change how the mouse cursor looks in game dependent on what it’s hovering over and stuff (in game) and how to hide (the actual cursor) While it’s in the window

Any Help, or is that not a thing yet?

Edit: Oh Any How would one do it so it works on any Desktop platform (not just only linux but so it works on windows and mac too?) Thanks!

:bust_in_silhouette: Reply From: henriquelalves

You can do it in two ways, as far as I know.

One is to hide the mouse cursor (set_mouse_mode(MOUSE_MODE_HIDDEN)) and creating a “Cursor” node yourself, which is just going to follow the mouse x and y positions, and interact with the stuff in the way you want.

The other method is by using set_default_cursor_shape, although I’m not too sure about how it goes performance-wise if you change it too often; and it gives you less freedom in interaction (as you can only iterate through the cursor constants of the control node), so I really recommend the first option.


I really love the selected answer.

using Input.set_custom_mouse_cursor()
but in case anyone needs to know how to implement this answer too :


Godot Doc for Input.set_mouse_mode()
Input.set_mouse_mode( pass it 0,1,2,or 3 )

Godot Doc for Input.MOUSE_MODE_…
Member constants defined in Input you can use ( identical to using 0-3 )

Input.set_mouse_mode( Input.MOUSE_MODE_VISIBLE )  # or pass 0 as parameter
Input.set_mouse_mode( Input.MOUSE_MODE_HIDDEN )   # or 1
Input.set_mouse_mode( Input.MOUSE_MODE_CAPTURED ) # or 2
Input.set_mouse_mode( Input.MOUSE_MODE_CONFINED ) # or 3

NOTE: Godot 2.1.4 set_mouse_mode() only has modes 0,1,2 ;
Input.MOUSE_MODE_CONFINED added in 3.0 alpha


Godot Doc for Control.set_default_cursor_shape()
accepts one number between 0 and 16 as a parameter.

N O T E S :

  • Only changes the cursor when it is directly above the node
    that called
    set_default_cursor_shape( int 0…16 )
  • If the node that calls set_default_cursor_shape(int)
    is partially covered by a child node (or sibling node)
    only hovering over the non-covered parts will change the cursor

Godot Doc for Control’s Numeric Constants
class Control has 17 constants defined for each cursor shape mode you can pass

example : set_default_cursor_shape( Control.CURSOR_WAIT )
example of each in the code your can try below


Simple scene + code to test set_default_cursor_shape() :


=== Scene Setup ===

  1. Make a new scene,
  2. Click tab for 2D
  3. Add a new Panel node to the scene
    (found under Node → CanvasItem → Control → Panel)
  4. Resize Panel to a comfortable size
    (we’ll be clicking it)
  5. Add a .gd script to your Panel
  6. Paste the code below
    (be sure to uncomment the if statement for either 2.1.4 or 3.0 alpha)
  7. Add back the TAB characters
  • Type a TAB in Godot.
  • Select 1 tab character (drag mouse or shift+arrow keys)
  • ctrl+c
  • ctrl+r (for replace)
  • in the first box, type 4 spaces
  • in the second box, ctrl+v paste your tab character
  • click Replace All
    I had to click “Replace All” 3 times
  1. Press F6
    or click the button “Play the edited scene
  2. Click + see your cursor change! + click + click
    (see Output window to see which mode it is in)

=== determining InputEvent subclass type in _input(event): differs … ===

NOTE:
Godot 3.0 alpha 1 has removed the member variable type
from class InputEvent, so the code will be different
depending on whether you run using 3.0 alpha or using 2.1.4

for 3.0 alpha — uncomment this if statement on line 17
if( event is InputEventMouseButton and event.is_pressed() ):

for 2.1.4 ---------- uncomment this if statement on line 20
if( event.type == InputEvent.MOUSE_BUTTON and event.is_pressed() ):

#=== .gd script to test set_default_cursor_shape(int shape)===

remember to replace sets of 4 spaces with TAB character

# -- Have a wonderful day -- 
#  ~ G r a s s H 0 P E r ~

extends Panel

var cursor_set_to = 0

func _ready():
    set_process_input(true)

func _input(event):

    ## if statement depending on your version of Godot goes here : 
    # ------------------------------------------------------------
    
    ## for 3.0 alpha -- uncomment this if
    # if( event is InputEventMouseButton and event.is_pressed() ):
    
    ## for 2.1.4 -- uncomment this if
    # if( event.type == InputEvent.MOUSE_BUTTON and event.is_pressed() ):

        cursor_set_to += 1

        if cursor_set_to > 16 :
            cursor_set_to = 0

        set_default_cursor_shape(cursor_set_to)


        if cursor_set_to == Control.CURSOR_ARROW :
            print( "CURSOR_ARROW = 0" )
        if cursor_set_to == Control.CURSOR_IBEAM :
            print( "CURSOR_IBEAM = 1" )
        if cursor_set_to == Control.CURSOR_POINTING_HAND :
            print( "CURSOR_POINTING_HAND = 2" )
        if cursor_set_to == Control.CURSOR_CROSS :
            print( "CURSOR_CROSS = 3" )
        if cursor_set_to == Control.CURSOR_WAIT :
            print( "CURSOR_WAIT = 4" )
        if cursor_set_to == Control.CURSOR_BUSY :
            print( "CURSOR_BUSY = 5" )
        if cursor_set_to == Control.CURSOR_DRAG :
            print( "CURSOR_DRAG = 6" )
        if cursor_set_to == Control.CURSOR_CAN_DROP :
            print( "CURSOR_CAN_DROP = 7" )
        if cursor_set_to == Control.CURSOR_FORBIDDEN :
            print( "CURSOR_FORBIDDEN = 8" )
        if cursor_set_to == Control.CURSOR_VSIZE :
            print( "CURSOR_VSIZE = 9" )
        if cursor_set_to == Control.CURSOR_HSIZE :
            print( "CURSOR_HSIZE = 10" )
        if cursor_set_to == Control.CURSOR_BDIAGSIZE :
            print( "CURSOR_BDIAGSIZE = 11" )
        if cursor_set_to == Control.CURSOR_FDIAGSIZE :
            print( "CURSOR_FDIAGSIZE = 12" )
        if cursor_set_to == Control.CURSOR_MOVE :
            print( "CURSOR_MOVE = 13" )
        if cursor_set_to == Control.CURSOR_VSPLIT :
            print( "CURSOR_VSPLIT = 14" )
        if cursor_set_to == Control.CURSOR_HSPLIT :
            print( "CURSOR_HSPLIT = 15" )
        if cursor_set_to == Control.CURSOR_HELP :
            print( "CURSOR_HELP = 16" )
                                                                                                #Legal: CCzero

Hope this helps someone someday.
Or provides a bit of entertainment.

Peace,
~ G r a s s H 0 P E r ~

Grass H0PEr | 2017-10-07 02:45

:bust_in_silhouette: Reply From: PixelWizzard

I have not tried this myself yet, but in the project settings, under the display tab, there is an option called custom_mouse_cursor. If I’m not wrong, you can change you default cursor there.

:bust_in_silhouette: Reply From: The_Duskitty

After Looking around (and reading the other answers)

I decided that the code to solve my problem was

Input.set_custom_mouse_cursor()

Works Splendedly

Hi, it works amazing, just one question. How do you make it back to the default?. Thanks in advance! :).

two_headed_goblin | 2016-10-28 02:59

+1 to the above comment. How do you turn it back to default?

Suchaaver Chahal | 2016-11-16 22:54

@Such, I do: Input.set_custom_mouse_cursor(null)

wombatTurkey | 2017-04-06 08:45

Mouse cursor position is off when set this way. Is it possible to change positioning via the code?

jarlowrey | 2021-02-26 19:25