Error preloaded path must be a string

Godot Version

Godot 4.2.1

Question

Hey all, so I’m currently making a ability system for the 2d game I’m making and I’m having a bit of trouble making getting the player code to recognise the ability that is picked up. Here is the code that I’m using for the “pick_up”

class_name ability_pick_up
extends Node2D

var next_ability = preload("res://Abilities/explosion.gd")

func _on_area_2d_body_entered(body):
	if body.is_in_group("Player_body"):
		body.current_ability = next_ability
		self.queue_free()

Where when i try to check what is actually being transfered from next ability to current ability it prints “<GDScript#-9223371980416219494>”
But when i try to preload(character.current_ability) i get the error in the title

Any and all help is appreciated

Your preload is only for a script hence <GDScript#-922...>, what type is your body.current_ability looking for? You may have to instantiate the script, or create a node to attach the script to.

You can only use static strings with preload. To do that with a variable, use load instead.

When i use load i get the error “cannot convert argument from object to string”

You still want to use your script path with load/preload, it doesn’t makes sense to try to load the character’s current_ability if you want to change it to explosion.gd, so you must load explosion.gd then instantiate what ever the script is and assign it to the current_ability

I’m not sure i understand the question but a little while ago i made an archer enemy with this script to shoot arrows and i thought that i could sort of repurpose that to an ability system for my character

		const Arrow = preload("res://Enemy_archer/Arrow.tscn")
		var New_Arrow = Arrow.instantiate()
		var Arrow_offset = Vector2i(0,-10)
		New_Arrow.global_position = character.global_position + Vector2(Arrow_offset)
		character.add_sibling(New_Arrow)

Where instead of arrows it would be specific abilities that would be determined by what was last picked up.

So it would look something like this:

func on_enter():
	var ability1 = load(character.current_ability)
	var new_ability1 = ability1.instantiate()
	character.add_sibling(new_ability1)

Similar to the arrows you have to instantiate it, notice Arrow.instantiate() and your applying it through add_sibling which takes a Node type. However your ability is trying to apply through body.current_ability = new_ability, but I don’t know what type current_ability is, the arrow is a scene .tscn so Node is given, this explosion is a script .gd so it could be any type.

I’m sorry I am new to godot
When you say type. Are you asking if it’s a scene or a script it’s trying to load?
Right now current ability is defined as:

var current_ability = null

That current_ability definition would be a great way to show me the type, but equals null doesn’t rule out much. What does your explosion.gd script extend?

aha after messing around a bit i found out that this works

func on_enter():
	var ability1 = character.current_ability.instantiate()
	character.add_sibling(ability1)

I think it’s because that the load() expects a string but since i’ve already used preload to change it to a packed scene it dosen’t work
Thank you for the help :slight_smile: I understand it a lot better now :))

Seems like a good way to use the ability, much like the arrow example. Though the initial question was about picking up the ability, not using it; is the func _on_area_2d_body_entered working correctly too? Can you show that function?

Yeah, It’s still the same as when i posted the original post