Node not found on calling function from preloaded script

Godot Version

version 4.2.1

Question

So i’m calling a function from a preloaded script fire. But on running the program i’m getting this error:

FireActivate(): Node not found: “AnimatedSprite2D” (relative to “StaticBody2D”).

I also tried preloading script under _ready() but i got the same error.

main.gd:

extends Node2D

var fire = preload("res://fire.gd").new()
func _ready():
    #if $Player.hit == true:
        #set_process_input(false)
    
func _physics_process(delta):
    Saw()
    for i in $Player.get_slide_collision_count():
        var collision = $Player.get_slide_collision(i)
        print("Collided with: ", collision.get_collider().name)
        
        box(collision)
        if collision.get_collider().name == "Trampoline":
            Trampoline()
        elif collision.get_collider().name.begins_with("Spikes"):
            Spikes()
            $MetalHitSound.play()
        elif collision.get_collider().name.begins_with("Saw"):
            $Player.die()
            $MetalHitSound.play()
        elif collision.get_collider().name.begins_with("Fire"):
            fire.FireActivate(collision)

func Trampoline():
    $Trampoline/AnimatedSprite2D.play("Jump")
    $Player.velocity.y = -1600
    $Trampoline/sound.play()
    
func Spikes():
    $Player.die()

func Saw():
    var speed = 5
    %PathFollow2D.set_progress(
        %PathFollow2D.get_progress()+speed)
    
func box(collision):
    if collision.get_collider().name.begins_with("Box"):
        $Box/AnimatedSprite2D.play("hit")
        $Player.velocity.y = -700
    else:
        $Box/AnimatedSprite2D.play("idle")

fire.gd:

extends StaticBody2D

var FireHit = false
    
func FireActivate(collision):
    if collision.get_collider().name.begins_with("Fire"):
        FireHit = true
        if FireHit:
            $AnimatedSprite2D.play("hit")
            $AnimatedSprite2D.play("on")
            $FireTimer.start(3)

func _on_timer_timeout():
    $AnimatedSprite2D.play("off")
    FireHit = false

this line alone doesnt look right, why would you create a new script of fire that extends StaticBody2D that’s a node and its FireActivate function actually calling a node that fire itself isnt even spawned in scene tree, how does fire know a node of AnimatedSprite2D if it itself not spawned as a node in a scene?
the $ is a shorthand of get_node method of Node type.
read here: $NodePath

i see you actually can has a scene of fire, but instead of instantiating the PackedScene, you create new script.

what you can do is:

extends Node2D

const fire = preload("res://fire.tscn")
func _ready():
    #if $Player.hit == true:
        #set_process_input(false)
    
func _physics_process(delta):
    Saw()
    for i in $Player.get_slide_collision_count():
        var collision = $Player.get_slide_collision(i)
        print("Collided with: ", collision.get_collider().name)
        
        box(collision)
        if collision.get_collider().name == "Trampoline":
            Trampoline()
        elif collision.get_collider().name.begins_with("Spikes"):
            Spikes()
            $MetalHitSound.play()
        elif collision.get_collider().name.begins_with("Saw"):
            $Player.die()
            $MetalHitSound.play()
        elif collision.get_collider().name.begins_with("Fire"):
            var new_fire_scene= fire.instantiate()
            add_child(new_fire)
            new_fire.FireActivate(collision)

func Trampoline():
    $Trampoline/AnimatedSprite2D.play("Jump")
    $Player.velocity.y = -1600
    $Trampoline/sound.play()
    
func Spikes():
    $Player.die()

func Saw():
    var speed = 5
    %PathFollow2D.set_progress(
        %PathFollow2D.get_progress()+speed)
    
func box(collision):
    if collision.get_collider().name.begins_with("Box"):
        $Box/AnimatedSprite2D.play("hit")
        $Player.velocity.y = -700
    else:
        $Box/AnimatedSprite2D.play("idle")

to actually spawn the scene to the SceneTree during runtime, then call the FireActivate function

1 Like

looks like i’m doing everything wrong
Actually, I have already placed multiple fire nodes in main.tscn, such as Fire, Fire2, Fire3… At first, I defined the FireActivate() function in main.gd, which has the line $Fire/AnimatedSprite2D.play(“hit”). However, this only calls the function on the first Fire node, not the others. I also tried defining signals, but they had the same result.
Is there a way to call the FireActivate() function from the fire.gd script on the particular Fire node that the player is currently colliding with?

Your method works well, but I have to set the position of all Fire nodes in the script, which is difficult. Or am I wrong? I’m still learning GDScript and don’t know a lot of things.

change to this:

extends Node2D

func _ready():
    #if $Player.hit == true:
        #set_process_input(false)
    
func _physics_process(delta):
    Saw()
    for i in $Player.get_slide_collision_count():
        var collision = $Player.get_slide_collision(i)
        print("Collided with: ", collision.get_collider().name)
        
        box(collision)
        if collision.get_collider().name == "Trampoline":
            Trampoline()
        elif collision.get_collider().name.begins_with("Spikes"):
            Spikes()
            $MetalHitSound.play()
        elif collision.get_collider().name.begins_with("Saw"):
            $Player.die()
            $MetalHitSound.play()
        elif collision.get_collider().name.begins_with("Fire"):
            var collided_fire=collision.get_collider()
            collided_fire.FireActivate(collision)

func Trampoline():
    $Trampoline/AnimatedSprite2D.play("Jump")
    $Player.velocity.y = -1600
    $Trampoline/sound.play()
    
func Spikes():
    $Player.die()

func Saw():
    var speed = 5
    %PathFollow2D.set_progress(
        %PathFollow2D.get_progress()+speed)
    
func box(collision):
    if collision.get_collider().name.begins_with("Box"):
        $Box/AnimatedSprite2D.play("hit")
        $Player.velocity.y = -700
    else:
        $Box/AnimatedSprite2D.play("idle")
1 Like

It worked. Thanks for help.