Basic Top Down Character Movement

Godot Version

4.3

Question

Hello,
First game I’m working on and my first time coding anything so bear with me.

Something seems to be wrong with the last 3 lines of code. I Checked and double checked to make sure I did the right thing. I tried a few different ones as well but I think this one makes the most sense to me.

extends CharacterBody2D

var movement_speed : float = 100.0
var charachter_direction : Vector2

enum States { IDLE, WALK, ATTACK, SLAM, DEAD, HIT }
var currentState = States.IDLE

func _physics_process(delta):
handle_state_transitions()

func handle_state_transitions():
if Input.is_action_pressed(“ui_left”) or Input.is_action_pressed(“ui_right”) or Input.is_action_pressed(“ui_up”) or Input.is_action_pressed(“Ui_down”):
currentState = States.WALK
else:
currentState = Status.IDLE

func perform_state_actions(delta):
match currentState:
States.MOVE:
charachter_direction.x = Input.get_axis(“ui_left”,“ui_right”)
charachter_direction.y = Input.get_axis(“ui_up”,“ui_down”)
charachter_direction = charachter_direction.normalized()

		if charachter_direction.x > 0 && charachter_direction.y == 0:
			$Sprite.animation = "walk"
		
		if charachter_direction.x < 0 && charachter_direction.y == 0:
			$Sprite.animation = "walk_left"
		
		if charachter_direction.y < 0:
			$Sprite.animation = "walk"
		
		if charachter_direction.y > 0:
			$Sprite.animation = "walk_left"
		
		velocity = charachter_direction * movement_speed * delta
	
	States.IDLE:
	velocity = velocity.move_toward(Vector2.ZERO, movement_speed * delta)
	$Sprite.animation = "idle"

Let me know what’s wrong with it.

Hi! There are two things you can do to make it easier for people to help you.

  1. Edit your post, select all the code, and press the little </> button in the editor - that will make the code show up with syntax highlighting and indentation (which is important in GDScript, where indentation affects what the code will do).
  2. Tell us a bit more about what isn’t working - what were you hoping the code would do, and what does it do instead?
3 Likes

Hello,
Thank you for letting me know, So the main issue is that script is not running. I want to use a normalized vector so that diagonal movement is not a big issue. I’m not too sure but I think the issue is with the IDLE animation. The character does not move after all the syntax was fixed. I tried to use a higher speed as well but no luck.

extends CharacterBody2D

var movement_speed : float = 2000.0
var charachter_direction : Vector2

enum States { IDLE, WALK, ATTACK, SLAM, DEAD, HIT }
var currentState = States.IDLE

func _physics_process(delta):
	handle_state_transitions()
	perform_state_actions(delta)
	move_and_slide()

func handle_state_transitions():
	if Input.is_action_pressed("ui_left") or Input.is_action_pressed("ui_right") or Input.is_action_pressed("ui_up") or Input.is_action_pressed("ui_down"):
		currentState = States.WALK
	else:
		currentState = States.IDLE
	
func perform_state_actions(delta):
	match currentState:
		States.WALK:
			charachter_direction.x = Input.get_axis("ui_left","ui_right")
			charachter_direction.y = Input.get_axis("ui_up","ui_down")
			charachter_direction = charachter_direction.normalized()
			
			if charachter_direction.x > 0 && charachter_direction.y == 0:
				$Sprite.animation = "walk"
			
			if charachter_direction.x < 0 && charachter_direction.y == 0:
				$Sprite.animation = "walk"
			
			if charachter_direction.y < 0:
				$Sprite.animation = "walk"
			
			if charachter_direction.y > 0:
				$Sprite.animation = "walk"
			
			velocity = charachter_direction * movement_speed * delta
		
		States.IDLE:
			velocity = velocity.move_toward(Vector2.ZERO, movement_speed * delta)
			$Sprite.animation = "idle"

Ok, I don’t see anything immediately suspicious in the code, but I’m still wondering: The script does not run? Does that mean there are errors (and if so, what do they say?), or just that nothing happens? If you print something from your _physics_process function, does it actually show up? Is the script attached to a node, and is that node a CharacterBody2D?

1 Like

So the message that pops up in the Stack trace is
Invalid assignment of property or key ‘animation’ with value of type ‘String’ on a base object of type ‘null instance’.

And error is
player_1.gd:43 @ perform_state_actions(): Node not found: “Sprite” (relative to “/root/Charachterbody2D”).

Another ting to note is I haven’t messed with the collisions yet but I have a CollisionShape2D as a child of the CharachterBody2D.

I’m super new to coding so I may not understand some of the jargon.

If it helps I have also got the nodes here so that its a bit clearer.

and I tried a bunch of different ways to do it too. But I’m still getting the same error.

Hello,

Went all the way back and decided to start from scratch. I completely redid the code. It was all working until I put in the animations for the sprite. No errors in the script itself but I don’t know if its something to do with the nodes.

extends CharacterBody2D

@onready var anim = $AnimatedSprite2D


@export var speed:float = 200.0


var is_moving:bool = false
var dir:String = "none"




func _ready():
	pass


func _process(delta):
	pass


	if Input.is_action_pressed("ui_left"):
		velocity = Vector2.LEFT * speed
		is_moving = true
		dir = "left"
	
	elif Input.is_action_pressed("ui_right"):
		velocity = Vector2.RIGHT * speed
		is_moving = true
		dir = "right"
	
	elif  Input.is_action_pressed("ui_up"):
		velocity = Vector2.UP * speed
		is_moving = true
		dir = "up"
	
	elif  Input.is_action_pressed("ui_down"):
		velocity = Vector2.DOWN * speed
		is_moving = true
		dir = "down"
	
	else:
		velocity = Vector2.ZERO
		is_moving = false
	
	
	move_and_slide()
	
	
	
	
	#animations need different code
	if velocity.x < 0:
		anim.flip_h = true
	else:
		anim.flip_h = false
	
	
	if is_moving == true:
		anim.play = "walk"
	
	elif is_moving == false:
		anim.play = "idle"
	

Here is the error message I got,

and this is the node structure I’m using

Let me know if anyone sees anything strange here.

Thanks