This site is currently in read-only mode during migration to a new platform.
You cannot post questions, answers or comments, as they would be lost during the migration otherwise.
+1 vote

Hi everyone,

I am a newbie and I have spent the last 8ish hours trying to figure out how to do this.
I also couldn't find the answer browsing the web.

Basically, what I would like to do is enable/disable a button every time that the player enters or leaves an area. The thing is that the button and the area are in two different scenes.

What I have done is the following:

  • I created a global singleton script with the button node as variable

  • in the script of the button node I put:

    Global.slotButton = self

  • and in the script of the area scene I connected the signal:

    onArea2Dbodyentered(_body):
    Global.slotButton.disabled = false (because I set it to start on disabled)

    onArea2Dbodyexited(_body):
    Global.slotButton.disabled = true

I have also tried to put a function in the button node like:

func test():
disabled =! disabled

and then call it on the signal callback. and a bunch of similar variations like set_disabled() etc., but nothing works, the button stays in the same status that it starts with.

The connection works because I tried with a print() in the test function in the button node and it prints every time that the body enters or exits.

I have also checked if my syntax was correct by connecting a function to a keyboard input to disable and enable the button and this one works.

There is definitely something that I am missing but my brain feels a bit like a mush atm :).

Help please?

Godot version 3.2.3
in Engine by (13 points)

1 Answer

0 votes

When you say that the button and the area are in two different scenes, where do they exist in your game's main scene?

I presume the node structure of your game's main scene looks like this:

  • Main scene

    • Scene with button
    • Scene with area

If this is the case, what you should do is attach a script to the scene with the area. Give this scene's script a signal; I will call it "areaentered" as an example. Connect the area's area_entered signal to a method in this scene's script, where you emit the script's "areaentered" signal.

# SceneWIthArea.tscn
extends Node

signal area_entered

func _on_Area2D_area_entered(_area: Area2D) -> void:
    emit_signal("area_entered")

Next, attach a script to the main scene. With the scene with the area, connect its "area_entered" signal to a method in the main scene. In this method you can access the scene with the button, where you'd disable the button.

# Main.tscn
extends Node

onready var scene_with_button = $SceneWithButton as Node

func _on_SceneWithArea_area_entered() -> void:
    var button := scene_with_button.get_node("Button") as Button
    button.disabled = not button.disabled

Does this accurately address your code and the problem you are facing?

by (120 points)

Thanks for your reply.

So, the thing is that the structure is a bit more complicated and I have got many of the areas that I want to use for that.

The situation is more like:

Scene --> instanced scene --> several instanced scenes --> several instanced area2d scenes for each of the previous scenes

Scene --> instanced scene --> instanced scene --> instanced scene --> several instanced button scenes

So I can't really do that for all of them in the main game scene.

That is why I wanted to do find a way to connect the "reference" script of both button scenes and area scenes through a singleton

And I still can't figure out why what I tried doesn't work.

Thanks though :).

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.