Skip to content

Instantly share code, notes, and snippets.

@sjvnnings
Created September 5, 2021 22:42
Show Gist options
  • Save sjvnnings/6b54a962f4c72758b182c49f655ed4e8 to your computer and use it in GitHub Desktop.
Save sjvnnings/6b54a962f4c72758b182c49f655ed4e8 to your computer and use it in GitHub Desktop.
A Simple JRPG-style cursor script in Godot. To use, just set the menu_parent_path property in the editor to the container your menu options are stored in.
extends TextureRect
export var menu_parent_path : NodePath
export var cursor_offset : Vector2
onready var menu_parent := get_node(menu_parent_path)
var cursor_index : int = 0
func _process(delta):
var input := Vector2.ZERO
if Input.is_action_just_pressed("ui_up"):
input.y -= 1
if Input.is_action_just_pressed("ui_down"):
input.y += 1
if Input.is_action_just_pressed("ui_left"):
input.x -= 1
if Input.is_action_just_pressed("ui_right"):
input.x += 1
if menu_parent is VBoxContainer:
set_cursor_from_index(cursor_index + input.y)
elif menu_parent is HBoxContainer:
set_cursor_from_index(cursor_index + input.x)
elif menu_parent is GridContainer:
set_cursor_from_index(cursor_index + input.x + input.y * menu_parent.columns)
if Input.is_action_just_pressed("ui_select"):
var current_menu_item := get_menu_item_at_index(cursor_index)
if current_menu_item != null:
if current_menu_item.has_method("cursor_select"):
current_menu_item.cursor_select()
func get_menu_item_at_index(index : int) -> Control:
if menu_parent == null:
return null
if index >= menu_parent.get_child_count() or index < 0:
return null
return menu_parent.get_child(index) as Control
func set_cursor_from_index(index : int) -> void:
var menu_item := get_menu_item_at_index(index)
if menu_item == null:
return
var position = menu_item.rect_global_position
var size = menu_item.rect_size
rect_global_position = Vector2(position.x, position.y + size.y / 2.0) - (rect_size / 2.0) - cursor_offset
cursor_index = index
@Shuhkky
Copy link

Shuhkky commented May 27, 2024

`extends TextureRect

@export var menu_parent_path : NodePath
@export var cursor_offset : Vector2

@onready var menu_parent := get_node(menu_parent_path)

var cursor_index : int = 0

func _process(delta):
var input := Vector2.ZERO
if Input.is_action_just_pressed("up"):
input.y -= 1
if Input.is_action_just_pressed("down"):
input.y += 1
if Input.is_action_just_pressed("right"):
input.x += 1
if Input.is_action_just_pressed("left"):
input.x -= 1

if menu_parent is VBoxContainer:
	set_cursor_from_index(cursor_index + input.y)
elif menu_parent is HBoxContainer:
	set_cursor_from_index(cursor_index + input.x)
	
if Input.is_action_just_pressed("ui_select"):
	var current_menu_item := get_menu_item_at_index(cursor_index)
	if current_menu_item != null:
		if current_menu_item.has_method("cursor_select"):
			current_menu_item.cursor_select()

func get_menu_item_at_index(index : int) -> Control:
if menu_parent == null:
return null
if index >= menu_parent.get_child_count() or index < 0:
return null
return menu_parent.get_child(index) as Control

func set_cursor_from_index(index : int) -> void:
var menu_item := get_menu_item_at_index(index)

if menu_item == null:
	return
	
var postion = menu_item.global_position
var menusize = menu_item.size

global_position = Vector2(position.x, postion.y + menusize.y) - (size / 2) - cursor_offset
print(globaL_position)
cursor_index = index`

Here is the script for the "Menu Cursor" Scene.

Here is a screenshot of the problem:

Error

In this screenshot, the cursor should be appearing at the red circle, however its position is sent far off the camera. (Position Circled in red)

@Beancan7
Copy link

var menu_position = menu_item.global_position
var menu_size = menu_item.size

global_position = Vector2(menu_position.x, menu_position.y + (menu_size.y / 2.0)) - (size / 2.0) - cursor_offset

You need to change your position variable name since position is referencing the current position of your pointer which changes with every iteration of _process so it keeps moving away as the number gets bigger. At least, that's what was wrong with mine

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment