Invalid operands 'Nil' and 'int' in operator '<='

Godot Version

3.5.3 on Linux Debian

Question

Trying to use code from this tutorial:

However, the animation part

func _process(delta):
	AnimationLoop()


func AnimationLoop():
	var anim_direction = "NW"
	var anim_mode = "Idle"
	var animation
	if moving_direction <= 15 and moving_direction >= -15:
		anim_direction = "E"
	if moving_direction <= 60 and moving_direction >= 15:
		anim_direction = "SE"
	elif moving_direction <= 120 and moving_direction >= 60:
		anim_direction = "S"
	elif moving_direction <= 165 and moving_direction >= 120:
		anim_direction = "SW"
	elif moving_direction >= -60 and moving_direction <= -15:
		anim_direction = "NE"
	elif moving_direction >= -120 and moving_direction <= -60:
		anim_direction = "N"
	elif moving_direction >= -165 and moving_direction <= -120:
		anim_direction = "NW"
	elif moving_direction <= -165 and moving_direction >= 165:
		anim_direction = "W"
	
	if moving == true:
		anim_mode = "Walk"
	elif moving == false:
		anim_mode = "Idle"
	animation = anim_mode + "_" + anim_direction
	get_node("AnimationPlayer").play(animation)

always returns “Invalid operands ‘Nil’ and ‘int’ in operator ‘<=’” error on

if moving_direction <= 15 and moving_direction >= -15:

line.

Debugger hints at
“at function: AnimationLoop”, the very first “<=” sign, and
“at function: _process”. No errors in Errors tab besides hinting at using _delta instead of delta.

With these animation code parts, game crashes at start. Without them, it plays normally.

Also found this issue: Invalid operands 'int' and 'Nil' in operator '+' when running ANY project on Linux in Godot Editor (64bit version) in 64bit system · Issue #30848 · godotengine/godot · GitHub
which might be related to the problem?

Do you initialize moving_direction somewhere? The error hints that it’s not initialized

var moving_direction
moving_direction = rad2deg(destination.angle_to_point(position))

“Empty” var for it is in the tutorial video, and somehow it worked for him.
I tried switching it to
var moving_direction = 0
and magically it works!

It’s hard to be sure without seeing the full code, but from this I wonder if the problem was related to where in the script you wrote your var moving_direction line? You would have probably wanted to include it inside your AnimationLoop func with the other var lines at the top, but in the code you shared that line seems to be somewhere else. Then it may work if you initialize it to the angle you’re expecting, instead of just to 0.

Full code

extends KinematicBody2D

var max_speed = 400
var speed = 0
var acceleration = 1200
var moving_direction = 359
var moving = false
var destination = Vector2()
var movement = Vector2()

func _unhandled_input(event):
if event.is_action_pressed(“click”):
moving = true
destination = get_global_mouse_position()

func _process(delta):
AnimationLoop()

func _physics_process(delta):
MovementLoop(delta)

func MovementLoop(delta):
if moving == false:
speed = 0
else:
speed += acceleration * delta
if speed > max_speed:
speed = max_speed
movement = position.direction_to(destination) * speed
moving_direction = rad2deg(destination.angle_to_point(position))
if position.distance_to(destination) > 100:
movement = move_and_slide(movement)
else:
moving = false

func AnimationLoop():
var anim_direction = “NW”
var anim_mode = “Idle”
var animation
if moving_direction <= 15 and moving_direction >= -15:
anim_direction = “E”
elif moving_direction <= 60 and moving_direction >= 15:
anim_direction = “SE”
elif moving_direction <= 120 and moving_direction >= 60:
anim_direction = “S”
elif moving_direction <= 165 and moving_direction >= 120:
anim_direction = “SW”
elif moving_direction >= -60 and moving_direction <= -15:
anim_direction = “NE”
elif moving_direction >= -120 and moving_direction <= -60:
anim_direction = “N”
elif moving_direction >= -165 and moving_direction <= -120:
anim_direction = “NW”
elif moving_direction <= -165 or moving_direction >= 165:
anim_direction = “W”

if moving == true:
	anim_mode = "Walk"
elif moving == false:
	anim_mode = "Idle"
animation = anim_mode + "_" + anim_direction
get_node("AnimationPlayer").play(animation)

With var moving_direction = 0, character can switch between idle/walk animations, and can face different directions, while with out = 0 game would just crash. It’s weird because the tutorial guy doesn’t have = 0.

Looks like you set it to 359 now in the code you shared and not 0? But I see what you mean. From the full script it definitely looks like the issue is that your moving_direction is being initialized to null implicitly/by default (as if you’d written var moving_direction = null) instead of to a number like you’d naturally expect, and that’s causing the problem on the very first frame before moving_direction is assigned to a number in the MovementLoop function.

That tutorial is a few years old and there might have been a change in Godot since then that made this not work. But it was an odd and fragile choice in the first place not to write var moving_direction = 0 just like the tutorial initializes all those other vars. Keep in mind that regardless of what a tutorial is doing, it is good practice to pretty much always initialize your vars with a var etc = [something]. That good practice will often save you from weird errors like this one.

I’m pretty new to Godot myself so I’m not sure whether it’s really my place to be critical, but I do know code in general and I can see a few generally odd and messy/error-prone choices in this tutorial. I think you could get better advice from other places, and not put too much credit into the exact way that this particular YouTuber is doing things.

1 Like

The initial error message looks like you are trying to compare a null value (moving_direction) with an int (15 or -15). Your var moving_direction is reaching that part of the code with a null value.

If this is when you are initializing the var:

moving_direction = rad2deg(destination.angle_to_point(position))

Then I guess destination is also null, or the evalution of this method is returning null for some reason. I would do print(rad2deg(destination.angle_to_point(position))) just to check what value rad2deg is returning. If null, keep going back and check if destination is also null.