I’m brand new to Godot after years of coding in BASIC (DarkBasic Pro, App Game Kit). Trying my hand at a simple 2d prototype to learn the engine.
What I want to do is have a custom node/script that handles movement for a bunch of CharacterBody2D scenes. These will be different shaped tiles that can be clicked and dragged around by the mouse.
For now, I’ve got a main.gd script which instantiates the scene “Inv_Tile_Cross”. That scene has a custom node attached to it classed as “Inventory_Tile_Control” which has a script ("inv_tile_node.gd) for detecting a left mouse click and positioning the sprite at the mouse position.
The “MouseClickLeft” action is in my project’s input map to detect the left mouse button.
I think I’m missing a crucial understanding of how to affect parent nodes with a script on a child node. For example, if instead of affecting position I simply print to the console, it works. And if I attach the script directly to the Inv_Tile_Cross scene, it also works. What am I doing wrong?
main.gd:
extends Node2D
var scene_inv_tile_cross = preload("res://inv_tile_cross.tscn")
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
var new_node = scene_inv_tile_cross.instantiate()
add_child(new_node)
position.x = 50
position.y = 50
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
pass
*inv_tile_node.gd:
extends Node2D
class_name Inventory_Tile_Control
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
if Input.is_action_just_pressed("MouseClickLeft"):
FollowMouse()
func FollowMouse():
position.x = get_global_mouse_position().x
position.y = get_global_mouse_position().y
This is the node structure on Inv_Tile_Cross. Note the custom node “Inventory_Tile_Control” attached as a child.
You can get the parent node in the child with get_parent(). Maybe try changing the position on that?
Also I’d try global_position. Normal position is relative to parent, which may not be what you want. You are getting the global position of the mouse , so set the global position too.
Excellent, that’s exactly what I needed. I also implemented global_position as well. For anyone wanting to see what my code looks like now, see below. Thank you!
extends Node2D
var scene_inv_grid = preload("res://scenes/inv_grid.tscn")
var scene_inv_tile_cross = preload("res://scenes/inv_tile_cross.tscn")
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
instance_inventory_grid(8,8)
instance_inventory_tile("cross",300,50)
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
pass
#Creates clickable inventory tiles
func instance_inventory_tile(tile_name,posx,posy):
match tile_name:
"cross":
var new_node = scene_inv_tile_cross.instantiate()
add_child(new_node)
var new_vector = Vector2(posx,posy)
new_node.set_global_position(new_vector)
_:
print("instance_inventory_tile: Tile not found")
#Creates the inventory from individual grid "nodes"
func instance_inventory_grid(countx,county):
for y in county:
for x in countx:
var new_node = scene_inv_grid.instantiate()
add_child(new_node)
var new_vector = Vector2(32 + (16*x),32+ (16*y))
new_node.set_global_position(new_vector)
extends Node2D
class_name Inventory_Tile_Control
var selected = false
var mouseclickx = 0
var mouseclicky = 0
var tileclickx = 0
var tileclicky = 0
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
pass
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
if Input.is_action_just_pressed("MouseClickLeft"):
selected = true
#stores mouse position at time of click
#mouseclickx = get_global_mouse_position().x
#mouseclicky = get_global_mouse_position().y
#stores tile sprite position at time of click
#tileclickx = position.x
#tileclicky = position.y
if Input.is_action_just_released("MouseClickLeft"):
selected = false
FollowMouse()
func FollowMouse():
if selected:
get_parent().position.x = get_global_mouse_position().x
get_parent().position.y = get_global_mouse_position().y