godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91.55k stars 21.26k forks source link

_get and _set are not called for real properties #99828

Open drusin opened 3 days ago

drusin commented 3 days ago

Tested versions

-Reproducible in Godot v4.3.stable, v4.2.stable, 4.0.3.stable, 4.0.stable

System information

Godot v4.3.stable - Windows 10.0.22631 - GLES3 (Compatibility) - NVIDIA GeForce GTX 1080 Ti (NVIDIA; 31.0.15.3713) - 12th Gen Intel(R) Core(TM) i5-12400F (12 Threads)

Issue description

When reading or writing real members defined in the class, _get and _set are ignored, they are only called for custom properties that are returned via _get_property_list. The documentation and meaningful special values like null suggest that this is not desired behavior.

Steps to reproduce

extends Control

var num := 5

func _get(property: StringName) -> Variant:
    if (property == "num"):
        return 6
    return null

func _ready() -> void:
    assert(num == 6, "_get is not working on real properties")

Minimal reproduction project (MRP)

get-bug_repro.zip

AThousandShips commented 3 days ago

This is pretty covered by the note on the documentation:

Note that a property must be present in get_property_list, otherwise this method will not be called.

I'm not sure what is missing from this description

dalexeev commented 3 days ago

See also:

dalexeev commented 3 days ago

Note that a property must be present in get_property_list, otherwise this method will not be called.

I'm not sure what is missing from this description

Script variables are present in get_property_list(), but _set() and _get() are not called for them. Probably _get_property_list() was meant, although that doesn't matter either, as long as the real variable exists.

You can use GDScript setters/getters for real variables. If you want to reuse the same setter/getter for multiple variables, there are separate proposals, like https://github.com/godotengine/godot-proposals/issues/6750.