Search code examples
godotgdscript

Avoid invoking setget function on starting up


I have a simple script like this:

tool
extends Node2D

export(int) var example_value=0 setget set_example_value

func set_example_value(val):
    print("Setting example_value=",val)
    
    #time/memory consuming code segment here
    
    example_value=val

and I set example_value to 3 and then exit the game engine
enter image description here

Now when I startup godot again the set_example_value() gets invoked to set the value,
Is there any way where the example_value will get set to 3 without the setter function being invoked?

why am I doing this?

because I have a time/memory consuming function which generates sprites when the value is changed,
so when I startup godot I don't want to recreate those sprites I only want the value to be changed to what it was before closing godot


Solution

  • Please read my answer for Play animation without invoking setget? first.


    The difference is that we will tell Godot to only store one of them. We can do that with _get_property_list. Thus, we are not going to use export with it.

    For example we can do this:

    var example_value := 0
    
    func _get_property_list() -> Array:
        return [
            {
                name = "example_value",
                type = TYPE_INT,
                usage = PROPERTY_USAGE_EDITOR
            }
        ]
    

    And the editor will show the variable because it has PROPERTY_USAGE_EDITOR, but it won't be stored because it does not have PROPERTY_USAGE_STORAGE.

    If it is not stored, then when loading Godot won't find it, and won't set it (note that it might be already stored before you told Godot to not store it… Saving the resource again will fix it, or use an external editor).


    Now the problem is that you are not saving the value at all. So we are going to have a two properties. One is only for the editor, and one is only for storage. And the storage one will not do the expensive process. Like this:

    tool
    extends Node
    
    var example_value := 0 setget set_example_value
    func set_example_value(mod_value:int) -> void:
        print("HELLO")
        example_value = mod_value
    
    
    var example_value_storage:int setget set_example_value_storage, get_example_value_storage
    func get_example_value_storage() -> int:
        return example_value
    
    
    func set_example_value_storage(mod_value:int) -> void:
        example_value = mod_value
    
    
    func _get_property_list() -> Array:
        return [
            {
                name = "example_value",
                type = TYPE_INT,
                usage = PROPERTY_USAGE_EDITOR
            },
            {
                name = "example_value_storage",
                type = TYPE_INT,
                usage = PROPERTY_USAGE_STORAGE
            }
        ]
    

    By the way, while we are at it, checking if the value is being modified in the setter might be a good idea:

    func set_example_value(mod_value:int) -> void:
        if example_value == mod_value:
            return
    
        print("HELLO")
        example_value = mod_value