CharacterBody2D Not Visibly Rotating

Godot Version

4.1.1

Question

My script believes wholeheartedly that my CharacterBody2D Node, Pickaxe, is the main window of the game, which it is not.

This has caused multiple issues with .visible() and .rotate().

Here is my code:

var limb
var rotating = false  # Degrees per step
var total_rotation = 0   # Total rotation so far
var beardy
var tilemap
var small_movement = Vector2(0.1, 0.1)
# Called when the node enters the scene tree for the first time.
func _ready():
	limb = $".."
	limb.visible = false
		# Load the scene containing the TileMap
	var scene = load("res://Scenes/Themine.tscn")
	
	# Instance the scene to access its nodes
	var scene_instance = scene.instantiate()
	
	# Find the TileMap node within the scene
	tilemap = find_tilemap_node(scene_instance)
	
	pickcollision = $"."
	emit_signal("pickcollision_ready")
	pickcollision.set_deferred("disabled", true)

func _process(delta):
	limb = $".."
	pickcollision = $"."
	transformation.origin = pickcollision.global_position
	# Check for key press
	if Input.is_action_pressed("ui_accept"):
		rotating = true
		pickcollision.set_deferred("disabled", false)
		#limb.visible = true;
		rotate_limb(delta)
	# Check for key release
	else:
		rotating = false
		pickcollision.set_deferred("disabled", true)
		limb.visible = true
		pickcollision.rotation = 0

func rotate_limb(delta):
	if rotating:
		# Rotate the limb
		limb.rotate(deg_to_rad(rotation_speed) * delta)
		
		# Update total rotation
		total_rotation += rotation_speed
		
		# Check if total rotation reaches 360 degrees
		if total_rotation >= 360:
			total_rotation = 0
			rotating = false

func find_tilemap_node(node):
	# Recursive function to find the TileMap node within the scene
	if node is TileMap:
		return node

func _on_beardycollision_ready():
	beardy = $"../../../CollisionPolygon2D"
	print("beardycollision ready")
	
func _on_picksprite_ready():
	print("picksprite ready")
	picksprite = $"../AnimatedSprite2D3"

Thanks for the help :frowning:

Hello, please clarify, as I do not see a Node reference or variable called “Pickaxe” or “pickaxe”. Can you please post the error you’re getting, if any, or highlight the section causing issues?

If, by chance, the issue is the first line of _ready(): limb = $"..", it may be possible that you are inadvertently getting a reference to the root node, and therefore your transformations are applying to the root, rather than the appropriate intended node. I would re-check your node-relationships, and post your tree so that we might be able to make recommendations.

Generally, it is bad practice for a child node to access its parent and perform operations on it directly - using signals would be preferred, and having the parent node react to these signals instead. The idiom “Call down, Signal up” applies.

Of course, here is the node tree:
image

The script is attached to CollisionShape2D under Pickaxe. I am attempting to access the Pickaxe node so both the CollisionShape2D and AnimatedSprite2D3 are rotated and made visible/invisible. I will try the signal method and get back to you, thanks!

Here is my new code:

extends CollisionShape2D

signal pickcollision_ready()

@export var transformation = Transform2D()
@export var rotation_speed = 1000 

@onready var pickcollision
var picksprite

var limb
var rotating = false  # Degrees per step
var total_rotation = 0   # Total rotation so far
var beardy
var tilemap
var small_movement = Vector2(0.1, 0.1)
# Called when the node enters the scene tree for the first time.
func _ready():
	limb = $".."
	PickRotate.visible_off()
		# Load the scene containing the TileMap
	var scene = load("res://Scenes/Themine.tscn")
	
	# Instance the scene to access its nodes
	var scene_instance = scene.instantiate()
	
	# Find the TileMap node within the scene
	tilemap = find_tilemap_node(scene_instance)
	
	pickcollision = $"."
	emit_signal("pickcollision_ready")
	pickcollision.set_deferred("disabled", true)

func _process(delta):
	limb = $".."
	pickcollision = $"."
	transformation.origin = pickcollision.global_position
	# Check for key press
	if Input.is_action_pressed("ui_accept"):
		rotating = true
		pickcollision.set_deferred("disabled", false)
		PickRotate.visible_on()
		PickRotate.rotate_limb(delta)
	# Check for key release
	else:
		rotating = false
		pickcollision.set_deferred("disabled", true)
		PickRotate.visible_off()
		pickcollision.rotation = 0

func find_tilemap_node(node):
	# Recursive function to find the TileMap node within the scene
	if node is TileMap:
		return node

func _on_beardycollision_ready():
	beardy = $"../../../CollisionPolygon2D"
	print("beardycollision ready")
	
func _on_picksprite_ready():
	print("picksprite ready")
	picksprite = $"../AnimatedSprite2D3"

and then PickRotate, the new script that is called:

extends CharacterBody2D

var limb
var rotating = false  # Degrees per step
var total_rotation = 0   # Total rotation so far
var beardy
var tilemap
@export var rotation_speed = 1000

func _ready(): 
	pass

func _process(_delta):
	pass

func rotate_limb(delta):
	limb = $"."
	rotating = true
	if rotating:
		# Rotate the limb
		limb.rotate(deg_to_rad(rotation_speed) * delta)
		print("I AM ROTATING")
		total_rotation += rotation_speed
		
		# Check if total rotation reaches 360 degrees
		if total_rotation >= 360:
			total_rotation = 0
			rotating = false

func visible_off():
	limb = $"."
	limb.visible = false

func visible_on():
	limb = $"."
	limb.visible = true

Question: The children of the Pickaxe node should also rotate along with the node itself, correct? Because it is making it to the correct part of the script, but it is just not visually rotating.