Play mathod about a null resulting var

Godot Version

4.0

Question

Hi, I had finally to replacing old version code with new one. The main difference is about animations. Former implementation was using AnimationPlayer, instead on new version i am adopting AnimatedSprite2D. I am stuck due to this error message whuc tells me I connot call play method on a null…Within the script I set:
@export var anim_sprite2D:AnimatedSprite2D

mmm, I am not sure about where Should I send the AnimatedSprite2D object I defined containing al animations to the var anim_sprite2D ??

Did you set the variable to the animated_sprite_2d in the inspector-tab?

Yes, as it is shown on the screenshot:

mmm, I have wrote in the scene file:
@export var anim_sprite2D:AnimatedSprite2D

but within inspector I cannot find the field anim_sprite2D field…for this reason i think I receive the error message: Cannot call method ‘play’ on a null value.

The inspector automatically changes the name to something more readable.

Can you show me the code where the error message is thrown?

I write the code :

extends Node2D

@export var player_controller: PlayerController
#@export var animation_player: AnimationPlayer
## @export var animation_tree:AnimationTree
@export var anim_sprite2D:AnimatedSprite2D

# @export var sprite: Sprite2D
#  @onready var animation_tree:AnimationTree =$AnimationTree

# @onready var spritePl: Sprite2D =$Sprite2D

func _ready():
	pass
	# animation_tree.active = true
	#spritePl= $Sprite2D      #animation_tree.--AnimationPlayer.Sprite2D
	
func _process(delta):
	update_anim_parameters()
'''
func _physics_process(delta: float):
	update_anim_parameters()
	if player_controller.electrified == true:
		animation_player.play("electricity")
		get_node("AudioStreamPlayer2D").playing = false
		
	
	else:
		if player_controller.direction == 1:
			spritePl.flip_h = false
		elif player_controller.direction == -1:
			spritePl.flip_h = true
		#####attacking animation
		#if player_controller.attacking == true:
		#	animation_player.play("attack")
		
		###########	
		#if abs(player_controller.velocity.x) > 0.0:
		#	animation_player.play("moving")
		#else:
		#	animation_player.play("idle")
	
		#if player_controller.velocity.y < 0.0:
		#	animation_player.play("jump")
		#elif player_controller.velocity.y > 0.0:
		#	animation_player.play("fall")   ### fall animation
'''		
		
func update_anim_parameters():
	print('update_anim_parameters method !!')
	if player_controller.velocity == Vector2.ZERO:
		#animation_tree["parameters/conditions/idle"] = true
		#animation_tree["parameters/conditions/is_walking"] = false
		anim_sprite2D.play("idle_left")
	else:
		anim_sprite2D.play("idle_right")
		#animation_player.play('walking')
		#animation_tree["parameters/conditions/idle"] = false  # parameters/conditions/idle
		#animation_tree["parameters/conditions/is_walking"] = true  # parameters/conditions/is_walking
		
		
	if Input.is_action_just_pressed("attack"):
		print('MISSING BLOCK')
		#animation_tree["parameters/conditions/attacking"] = true  # parameters/conditions/attacking
		#animation_player.play("attack")
	#else:
	#	animation_tree["parameters/conditions/attacking"] = false

hhmm thats weird. can you show in which line the error occurs?

Ok, I think to have step over just a lil bit ahead… but when i flip from one side to the other animation remain the same…the code is:

direction = Input.get_axis("go_left","go_right")
	if Glob.electricBlock == false:
		if  direction:
			velocity.x =direction*SPEED
		else:
			velocity.x = move_toward(velocity.x,0, SPEED)
	else:
		velocity.x = 0.0 #move_toward(velocity.x,0, 0)
		
	## manage direction

	if direction == 1 and Glob.electricBlock == false:
		anim_Sprite2D.flip_h= false
		anim_Sprite2D.play("idle_left")
	elif direction ==-1 and Glob.electricBlock == false:
		anim_Sprite2D.flip_h= true
		anim_Sprite2D.play("idle_right")

in the upper code you defined your animatedsprite like this: “anim_sprite2D”. In the code snippet you send now it says: “anim_Sprite2D”. Maybe thats the problem?

Hi, I checked the whole code and used the correct variable names, but what concerns me is that I cannot implementing right way for managing animation for turning …

This is the code till now:

func _physics_process(delta: float) -> void:
	# Add the gravity.
	if not is_on_floor():
		velocity.y += gravity_sys*delta
	
	print('Glob.electricBlock is '+str(Glob.electricBlock))	
	if Input.is_action_pressed("Jump") and is_on_floor() :
		if(Glob.electricBlock == false):
			velocity.y =jump_mult*JUMP_VELOCITY
				
	direction = Input.get_axis("go_left","go_right")
	if direction == 1: #and Glob.electricBlock == false:
		anim_Sprite2D.flip_h= false
		anim_Sprite2D.play("idle_left")
	elif direction ==-1: #and Glob.electricBlock == false:
		anim_Sprite2D.flip_h= true
		anim_Sprite2D.play("idle_right")
	if Glob.electricBlock == false:
		if  direction:
			velocity.x =direction*SPEED
		else:
			velocity.x = move_toward(velocity.x,0, SPEED)
	else:
		velocity.x = 0.0 #move_toward(velocity.x,0, 0)
		
		
	move_and_slide()

I dont think you need to flip the sprite when you already have two different animations for left and right. just remove the “anim_Sprite2D.flip_h = …”

mmm, just to be clearer I set the updated code:

func _physics_process(delta: float) -> void:
	# Add the gravity.
	if not is_on_floor():
		velocity.y += gravity_sys*delta
	
	print('Glob.electricBlock is '+str(Glob.electricBlock))	
	if Input.is_action_pressed("Jump") and is_on_floor() :
		if(Glob.electricBlock == false):
			velocity.y =jump_mult*JUMP_VELOCITY
				
	var direction = Input.get_axis("go_left","go_right")
	
	move_and_slide()
	play_walk_animation(direction)
	
	if direction == 1: #and Glob.electricBlock == false:
		
		anim_Sprite2D.play("idle_right")
	elif direction ==-1: #and Glob.electricBlock == false:
		
		anim_Sprite2D.play("idle_left")
	if Glob.electricBlock == false:
		if  direction:
			velocity.x =direction*SPEED
			
		else:
			velocity.x = move_toward(velocity.x,0, SPEED)
	else:
		velocity.x = 0.0 
	
func play_walk_animation(direct):
	print('value of direction is: '+str(direct))
	if velocity.x > 0:
		anim_Sprite2D.play("walk_right")
	elif velocity.x < 0:
		anim_Sprite2D.play("walk_left")

i am getting strange behaviour: when I push arrow keys on keyboard It moves correctly along the right direction but animations played are run only when I finish to push the arrow key self

This is because you are setting the animation twice
1.:

2.:

You should look into "state-machine"s on youtube or something. They will help you prevent these kind of issues and make your code a lot clearer

ok, I will fix it as soon as possible!!! sorry for stupid problems I create but I have problems about my sight…

No need to apologize, these problems are not stupid.
State-Machines will make your code much clearer and easier to understand

1 Like

ok, for now turning on left/right works but what is giving me problems is the direction player is facing to…
I wrote following code:

func play_walk_animation(direct):
	
	#print('value of direction is: '+str(direct))
	if velocity.x > 0:
		anim_Sprite2D.play("walk_right")
	elif velocity.x < 0:
		anim_Sprite2D.play("walk_left")
	else:
		print('facing to: ',facing)
		if facing:
			anim_Sprite2D.play("idle_left")
		else:
			anim_Sprite2D.play("idle_right")

the part related to both moving on left and on right works; but facing remains always True..and when velocity.x =0 animation ran is “dle_left”..

then change the value of facing according to the last value of velocity:

func play_walk_animation(direct):
	
	#print('value of direction is: '+str(direct))
	if velocity.x > 0:
		facing = false
		anim_Sprite2D.play("walk_right")
	elif velocity.x < 0:
		facing = true
		anim_Sprite2D.play("walk_left")
	else:
		print('facing to: ',facing)
		if facing:
			anim_Sprite2D.play("idle_left")
		else:
			anim_Sprite2D.play("idle_right")