Correct usage of 2nd property for .connect(string signal, object target, string method)

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Larington
:warning: Old Version Published before Godot 3 was released.

My current project involves buttons that are re-used frequently. I’m struggling with finding a good description of how to go about setting the object target for adding a signal connection where the object target is not self.

Node hierarchy is:
Gameplay
->Menu
—>Menu buttons
->QuestLog
—>TutorialQuest

GodotScript is:

# Sets up a button with some text and tells it what function the signal should link to.
func assignChoiceToButton(num, displayText, command):
	get_node("ChoiceButton" + str(num)).show()
	#print("ChoiceButton" + str(num))
	get_node("ChoiceButton" + str(num)).set_text(displayText)
	#print(displayText)
	get_node("ChoiceButton" + str(num)).connect("pressed",self,command)
	if(num == 1):
		forgetsignal1 = command
	if(num == 2):
		forgetsignal2 = command
	if(num == 3):
		forgetsignal3 = command
	if(num == 4):
		forgetsignal4 = command
	if(num == 5):
		forgetsignal5 = command
	if(num == 6):
		forgetsignal6 = command
	if(num == 7):
		forgetsignal7 = command

func continuebuttonprompt(command):
	resetchoicebuttons()
	get_node("ChoiceButton7").connect("pressed",self,command)
	get_node("ChoiceButton7").set_text("continue...")
	forgetsignal7 = command

# This should clear the last signal applied to each of the buttons so they're ready for new signals to be assigned to them. 
func resetchoicebuttons():
	print("Choice Buttons Reset!")
	if(forgetsignal1 != "emptyvalue"):
		get_node("ChoiceButton1").disconnect("pressed",self,forgetsignal1)
	if(forgetsignal2 != "emptyvalue"):
		get_node("ChoiceButton2").disconnect("pressed",self,forgetsignal2)
	if(forgetsignal3 != "emptyvalue"):
		get_node("ChoiceButton3").disconnect("pressed",self,forgetsignal3)
	if(forgetsignal4 != "emptyvalue"):
		get_node("ChoiceButton4").disconnect("pressed",self,forgetsignal4)
	if(forgetsignal5 != "emptyvalue"):
		get_node("ChoiceButton5").disconnect("pressed",self,forgetsignal5)
	if(forgetsignal6 != "emptyvalue"):
		get_node("ChoiceButton6").disconnect("pressed",self,forgetsignal6)
	if(forgetsignal7 != "emptyvalue"):
		get_node("ChoiceButton7").disconnect("pressed",self,forgetsignal7)
	
	get_node("ChoiceButton1").hide()
	get_node("ChoiceButton2").hide()
	get_node("ChoiceButton3").hide()
	get_node("ChoiceButton4").hide()
	get_node("ChoiceButton5").hide()
	get_node("ChoiceButton6").hide()
	get_node("ChoiceButton7").show()
	forgetsignal1 = "emptyvalue"
	forgetsignal2 = "emptyvalue"
	forgetsignal3 = "emptyvalue"
	forgetsignal4 = "emptyvalue"
	forgetsignal5 = "emptyvalue"
	forgetsignal6 = "emptyvalue"
	forgetsignal7 = "emptyvalue"

So my question is, if I were trying to call the above code in “…/menu” from “…/QuestLog/TutorialQuest” what should I put instead of self for the object target? Thanks.

Random aside, for the moment I’ve cheated by copying the above code into the TutorialQuest node, but I’m not sure I want to be doing that for every single quest only to maybe rework it later.

Larington | 2017-01-12 17:17

Oh, in TutorialQuest I might setup a button like so:

assignQuestChoiceToButton(4, "I want to explore, curiosity drives me.", "stepOneAnswerB")

to then call

func stepOneAnswerB():
	get_node("../../Menu").addTextOutput("You: I want to explore, curiosity drives me.")
	get_node("../../Menu").addTextOutput("Guardsman: Exploration is not without its risks! I wish you luck in this endeavour!")
	stepTwo()

Larington | 2017-01-12 17:34

also, you maybe could try to use match: statement instead of your ‘if’ conditional statements . not that it’d fix anything, but looks like a good use for it.

trumpetfish1 | 2018-04-25 04:34

:bust_in_silhouette: Reply From: ingo_nikot

1.) instead of reating your code 7 times make it like

for choice in choice_list:
   #code for button creation and connection

choice_list could be an array or dictionary, you could fill it within the script or load it via .json.
here is an tutorial were someone did something like you want:
https://www.youtube.com/watch?v=aVutIoCGAfE&t=52s

2.) target_node = self.get_node(<path_to_node>)
button.connect(“pressed”,target_node,“name_of_the_method”)

your target_node needs a script with the method “name_of_the_method”. but im not shure if that is the right path. its cleaner imo to have the method who handles the signal in the same script were it gets connected.

I appreciate the advice. I must confess I had seen Happiecats video prior to starting this project. Whilst I saw the merits (And think it’s certainly worthwhile for others to check out her approach) in this particular case I opted to keep everything together in the same place rather than have the text out in JSON files.

To me it’s a case of, what works for one person may not be suitable for others, but I absolutely recommend anyone who reads this response checks the video.

Larington | 2017-01-13 01:29

:bust_in_silhouette: Reply From: bruteforce

Just pass a reference to another object :)!

connect("pressed", get_node("path/to/target/node"), funcName)

Thank you, this is the answer I was looking for, I should’ve guessed that would be the way to do it but my brain got fixated on the way the function call is handled in connect and tried to was sending a string like an idiot.

Larington | 2017-01-13 01:13