|
|
|
 |
Reply From: |
Zylann |
The problem you have is caused by the script referencing itself. Cyclic references are not well supported, and it’s something devs are working to improve in Godot 4.0. You should then be able to do what you said.
const HealthBar = preload("res://HealthBar.tscn")
...
var health_bar = HealthBar.instance()
I think this code works because it does not asks the resource loader to load your script while it is already in the process of loading it.
An alternative is to do this:
var healthbar = load("health_bar.gd").new()
Sorry, I don’t think I was clear. This was not cyclic, I was calling HealthBar.new()
from the UI.gd
script.
I’m trying to avoid using strings with filenames, but I’m not sure if it’s avoidable. I really don’t like having to call preload("res://HealthBar.tscn")
since there’s no guarantee I don’t move that file to another directory at some point.
frozenberg | 2020-03-11 17:07
var healthbar = HealthBar.new()
which did not work.
What do you mean by not working then? I’m not aware of another case where this wouldn’t work.
In Godot, the only ways to not write the path (or relative path) to an asset inside a script is to use an export
variable and assign it in the inspector, or use class_name
in the case of scripts. However, if that causes a cyclic reference, then you have no choice but to write it in the script using load
.
Zylann | 2020-03-11 19:18
My HealthBar
script:
extends CanvasLayer
class_name HealthBar
func _ready():
print("Health bar is ready!")
This is my UI
script:
extends Control
var X_OFFSET : int = 30
func add_monsters(monsters:Array):
for monster in monsters:
print("Adding this monster to the UI: %s" % monster.get_name())
var health_bar := HealthBar.new()
health_bar.offset = monster.position + Vector2(X_OFFSET, 0)
add_child(health_bar)
and none of my HealthBar
scenes get instanced/drawn.
frozenberg | 2020-03-11 20:20
Note that a script is not the same as a scene. When you create an instance of a script (with new()
), it creates only the object this script extends. This is because the same script can be on multiple scenes, and scripts don’t necessarily extend nodes.
If what you want is to instanciate a health bar scene dynamically, then class_name
is not what you are after. You have to either use an export
to assign the scene in the inspector, or load it by path.
Zylann | 2020-03-11 20:39
Thanks, this is the confirmation I was looking for. class_name/new()
is to be used for scripts/tools/custom data structures, while preload/load/instance()
should be used for scenes with arbitrary node structures.
frozenberg | 2020-03-11 20:46