xyz This is good to know. But the resource object was not created in the editor, I created it with my saving system at runtime and removed the contents from the array. _init()
is actually running and changing the values, but they are immediately overwritten by something else (Only the two variables that also appear in that text resource file I shared).
Something is emptying my array after constructor!
- Edited
Jesusemora I tried removing @export
before and nothing changed. Maybe it was cached so it's not registering? I'm curious as to why only those two variables appear in the text resource file I opened in VisualStudio.
- Edited
Godoten why only those two variables appear in the text resource file
The resource file will store only the values that override the defaults. You said you added tester=0
but your declared property name is not tester
, it's test_number
. The variable tester
is actually never declared in the code snippet you posted.
Hard to debug without seeing the whole thing.
- Edited
xyz Alright, so I "fixed" it. I deleted the @export
and the problem persisted. But then I also opened the file in VisualStudio, deleted characters_array = ArrayExtResource("2_r71wj")
and saved. Now it stopped overwritting my changes made in _init()
.
My take from this is that the @export
notation was cached to an empty array, even though I never used the inspector. to modify the array. But also, Godot didn't register that I removed the @export
until I manually removed the variable from the file. I'm using Godot 4.3.
- Edited
Godoten Umm. Post the exact resource class code and the code that manipulates the resource object(s). Without that, noone will be able to help you figure out what's happening.
The property value you set in the editor will override the value that's assigned at declaration, and the value assigned in _init()
will override the editor value, given that _init()
is executed either at runtime or in a tool script.
- Edited
Yes, reading Godot's docs I learned that the order is declaration
-> _init()
-> @export
. But removing the @export from the script was not removing the variable from the *.tres file (so doing it manually fixed the issue).
This was the code. I debugged a lot and didn't find anything that could be causing it:
extends Resource
class_name CharactersPack
@export var characters_array : Array[Character]:
set(value):
if value.is_empty():
print('It's being emptied!') # My debugger would stop here after _init()
characters_array = value
@export var pack_ID: int
var tester : int
func _init()->void:
if characters_array.is_empty():
add_character()
pack_ID = 33
tester = 39
func add_character(new_character : Character = Character.new()):
characters_array.append(new_character)
The resource was being instantiated by this code:
extends Node
class_name MainGame
const FILE_DIALOG = preload("res://Game/scenes/file_dialog.tscn")
@onready var editor_manager : EditorManager = %editorManager
func _on_open_characters_pressed() #UI button pressed
var file_browser = FILE_DIALOG.instantiate()
file_browser.file_was_selected.connect(on_open_file)
add_child(file_browser)
func on_open_file(resource_path : String)->void: #when selected a "*.tres" file using file_dialog
var temp = load(resource_path)
if temp.characters_array.is_empty(): # I added this to test if the _init had any effect.
print("It's still empty!")
editor_manager.start_editor(temp) #<- start editor asks for a CharactersPack as argument
Later editor_manager would try to access characters_array.front() and get an error for an empty array. Removing @export and manually deleting characters_array = ArrayExtResource("2_r71wj")
from the *.tres through VisualStudio fixed it (and debugger would not stop in the setter anymore).
- Edited
Godoten To add to this: I did another test by giving tester = 10
in _init()
, then adding tester to the *.tres file and giving it the value 99:
[gd_resource type="Resource" script_class="CharactersPack" load_steps=3 format=3 uid="uid://cplv1g7v0xojk"]
[ext_resource type="Script" path="res://Game/resources/characters_pack.gd" id="1_tumet"]
[ext_resource type="Script" path="res://Game/resources/character.gd" id="2_r71wj"]
[resource]
script = ExtResource("1_tumet")
characters_array = ArrayExtResource("2_r71wj")
pack_ID = 0
tester = 99
I can confirm tester = 99
overwrites tester's value set in _init()
, even though it doesn't have the @export
notation. So the vars written in the .tres file have priority over anything else during instantiation, and the only way to remove it is by editing the .tres file. This may be really confusing and hard to deal by beginners like me. I feel like removing the @export
should remove the var from the *.tres file too.
- Edited
Godoten I feel like removing the @export should remove the var from the *.tres file too.
It will but only when the engine touches the resource file after you edited the script. The resource file references the script, not the other way around. Hence the script has no way of keeping track of every resource file that references it in order to update them all.
If you see a value assignment in the resource file, that means that this value in an override set in the editor via the exported property. If you remove the @export tag from the script, this assignment will be deleted as soon as the editor or a runtime script touches the resource, but it won't happen immediately when you delete the @export tag from the resource script.
xyz this assignment will be deleted as soon as the editor or a runtime script touches the resource, but it won't happen immediately when you delete the @export tag from the resource script.
I did delete the @export and ran the game, so the editor should have reached the resource and updated it. But you are right, I tested it with a new file and it updated automatically. I have no idea what caused this, but at least now I know more about exports and the instantiation process. Thank you!