Skip to main content
added 2117 characters in body
Source Link
Theraot
  • 27.5k
  • 4
  • 52
  • 79

New Answer

The underlying reason of the problem is that the autoload (singleton) script is not the same on the scenario. When the player interacts with the instance on the scenario, the green door script interacts with the instance on autload (singleton).

There are a two solutions:

Option one: Don't use an autoload.

Now that green button has signals (as suggested in the original answer, kept for reference), you can connect them directly to the green door, or doors, in the scenario from the editor.

You would no longer need to connect those signals from code if you do it from the editor, of course.

Drawback: It can get complicated to connect all the signals for large scenarios.


Option two: Use a signal bus.

For those complicated large scenarios, there is a a common pattern in Godot: the signal bus.

To do it, you create a script and put in autoload (singleton), and that script will only defines signals. Nothing more. You would then emit those signals and connect them whenever you need them (knowing that being a singleton they are always available).

Let us say your singleton is called SignalBus (because, of course), and it has the signals "button_down" and "button_up" then in your green button code you can do this:

func _on_Green_Button_Area_body_entered(body):
    SignalBus.emit_signal("button_down")
    print("button is down")

func _on_Green_Button_Area_body_exited(body):
    SignalBus.emit_signal("button_up")
    print("button is up")

And in your green door code, you can connect to the SignalBus:

onready var door_collision = $CollisionPolygon2D

func _ready() -> void:
    SignalBus.connect("button_down", self, "_on_button_down")
    SignalBus.connect("button_up", self, "_on_button_up")

func _on_button_down():
    door_collision.set_disabled(true)
    print("unlocked")

func _on_button_up():
    door_collision.set_disabled(false)
    print("locked")

And that would be connecting all the green doors to all the green button via the signal bus.


Original Answer

New Answer

The underlying reason of the problem is that the autoload (singleton) script is not the same on the scenario. When the player interacts with the instance on the scenario, the green door script interacts with the instance on autload (singleton).

There are a two solutions:

Option one: Don't use an autoload.

Now that green button has signals (as suggested in the original answer, kept for reference), you can connect them directly to the green door, or doors, in the scenario from the editor.

You would no longer need to connect those signals from code if you do it from the editor, of course.

Drawback: It can get complicated to connect all the signals for large scenarios.


Option two: Use a signal bus.

For those complicated large scenarios, there is a a common pattern in Godot: the signal bus.

To do it, you create a script and put in autoload (singleton), and that script will only defines signals. Nothing more. You would then emit those signals and connect them whenever you need them (knowing that being a singleton they are always available).

Let us say your singleton is called SignalBus (because, of course), and it has the signals "button_down" and "button_up" then in your green button code you can do this:

func _on_Green_Button_Area_body_entered(body):
    SignalBus.emit_signal("button_down")
    print("button is down")

func _on_Green_Button_Area_body_exited(body):
    SignalBus.emit_signal("button_up")
    print("button is up")

And in your green door code, you can connect to the SignalBus:

onready var door_collision = $CollisionPolygon2D

func _ready() -> void:
    SignalBus.connect("button_down", self, "_on_button_down")
    SignalBus.connect("button_up", self, "_on_button_up")

func _on_button_down():
    door_collision.set_disabled(true)
    print("unlocked")

func _on_button_up():
    door_collision.set_disabled(false)
    print("locked")

And that would be connecting all the green doors to all the green button via the signal bus.


Original Answer

Source Link
Theraot
  • 27.5k
  • 4
  • 52
  • 79

This line:

onready var is_object_on_button = Green_Button.is_object_on_button

Is making a copy of the value when the Node enters the scene tree for the first time (just before _ready would run). That value never changes. The other script does not access it, nor modifies it.

Vaillancourt's advice in comments is correct, you should use Green_Button.is_object_on_button directly:

func _process(delta):
    if Green_Button.is_object_on_button:
        door_collision.set_disabled(true)
        print("unlocked")
    else:
        door_collision.set_disabled(false)
        print("locked")

You might also be interested in using signal. You can declare signals in your singleton, for example:

signal button_down
signal button_up

func _on_Green_Button_Area_body_entered(body):
    emit_signal("button_down")
    print("button is down")

func _on_Green_Button_Area_body_exited(body):
    emit_signal("button_up")
    print("button is up")

Then - given it is a singleton - you can connect to those signals anywhere from code:

onready var door_collision = $CollisionPolygon2D

func _ready() -> void:
    Green_Button.connect("button_down", self, "_on_button_down")
    Green_Button.connect("button_up", self, "_on_button_up")

func _on_button_down():
    door_collision.set_disabled(true)
    print("unlocked")

func _on_button_up():
    door_collision.set_disabled(false)
    print("locked")

See Custom signals and Connecting signals in code.