Godot Version
4.4.stable
Question
I am learning how to use Godot coming from both Unity and Unreal Engine. I have been following a Zenva course, and the most basic thing it teaches is how to move a 2D scene using the directional keys. I wanted to change the hierarchical structure of my scene for better organization, but this has resulted in the movement not working at all.
Having the CharacterBody2D node as the root for my ‘Player’ scene (this node containing all the code) makes the implementation work as inteded, but I wanted to have a base scene root (Node2D) with the main script for said scene, and then the rest of the necessary nodes (Sprite2D, CharacterBody2D) as children with their respective scripts.
I have been trying different approaches for this structure, but none seem to work. I have tried calling ‘move_and_slide()’ from the root (_characterBody2D.move_and_slide()), or calling specific functions that call ‘move_and_slide()’ from within the CharacterBody2D node, but while the code seems to work when debugging it (breakpoints inside the CharacterBody2D script are reached and execution paused) the ‘Player’ scene doesn’t move.
What would be the correct approach to do this? Do I always need to have the CharacterBody2D node as the scene root if I want it to ‘move_and_slide()’ or ‘move_and_collide()’?
Code
When the implementation worked I had all the code on a single script inside the CharacterBody2D node. When I rearranged the hierarchy, I tried to add one more script since the previous one didn’t work anymore (breakpoints were reached and execution paused, but the ‘Player’ scene didn’t move), and slightly modified the existing one. The updated hierarchy and code are below:
· Root (Node2D) code:
extends Node2D
@onready var _characterBody2D: PlayerMovement = $Player
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _physics_process(delta: float) -> void:
_characterBody2D.call_move_and_slide()
· Child (CharacterBody2D) code:
class_name PlayerMovement
extends CharacterBody2D
@export var _speed: float = 200
func _process(delta: float) -> void:
velocity = Vector2.ZERO
GetInput()
velocity *= _speed
func GetInput():
var inputDir = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
velocity = inputDir * _speed
velocity = velocity.normalized()
func call_move_and_slide() -> void:
move_and_slide()