[SOLVED] Sending messages to another gui_script

Hi! I can now create gui templates and use them in another gui. However, if I add a gui_script to a gui template and try to send a message to this script, it doesn’t work. But I think it should work, because it would help separate logic in a complex gui. Am I right or not?

1 Like

You are right about the architectural motivation, but in Defold, a GUI template is only a node prefab, not a reusable GUI component with its own running script.

When you add a .gui as a template inside another .gui, Defold instantiates the nodes, prefixes their ids, and ignores the template’s own gui_script.

“If a script is associated with a template GUI scene, the script is not part of the instance node tree. You may attach one single script to each GUI scene so your script logic needs to sit on the GUI scene where you have instantiated your templates.”

So only one script can be attached to the GUI scene where the template is instantiated.

So this will not work:

button.gui
  - button.gui_script   <-- ignored when button.gui is used as template

main.gui
  - template: button.gui

But still, for modularity, you can do:

button.gui -- reusable visual node template only

button.lua -- reusable logic module

main.gui
  - template: button.gui

In main.gui_script: require "directory_with_button.button" and handle the input and the whole logic.

2 Likes

Yes, but can it be changed if I make feature request? :slight_smile:

But how can I use it in gui template?

For example I have a button with 3 states (idle, hover, pressed). I make template and add 10 instances of this template to gui.

How can I mange states of this button without for loops in main gui?

1 Like

now I am handle it like this

	self.buttons = {
		{
			button = gui.get_node("button_ability1/button_sprite"),
			icon = gui.get_node("button_ability1/button_icon"),
			stroke = gui.get_node("button_ability1/button_stroke"),
			icon_scale = gui.get_scale(gui.get_node("button_ability1/button_icon")),
			action = hash("use_saw"),
			over = false,
			active = false
		},

		{
			button = gui.get_node("button_ability2/button_sprite"),
			icon = gui.get_node("button_ability2/button_icon"),
			stroke = gui.get_node("button_ability2/button_stroke"),
			icon_scale = gui.get_scale(gui.get_node("button_ability2/button_icon")),
			action = hash("use_gun"),
			over = false,
			active = false
		},
	}

and use for loop in on_input

		-- ability buttons
			for _, btn in ipairs(self.buttons) do
				if gui.pick_node(btn.button, action.x, action.y) then
					if not btn.active then
						btn.active = true
						local duration = 10
						if btn.action == hash("use_saw") then
							duration = config.player.saw_ability_duration
						elseif btn.action == hash("use_gun") then
							duration = config.player.boost_gun_duration
						end
						gui.set_color(btn.button, vmath.vector4(1, 1, 1, 0.5))
						gui.set_color(btn.icon, vmath.vector4(1, 1, 1, 0.5))
						gui.set_color(btn.stroke, vmath.vector4(1, 1, 1, 1))
						animate_hover(btn.icon, btn.icon_scale)
						animate_hover(btn.button, vmath.vector3(1))
						msg.post("player/root#player_stats", btn.action)
						timer.delay(duration, false, function ()
							btn.active = false
							gui.set_color(btn.button, vmath.vector4(1, 1, 1, 1))
							gui.set_color(btn.icon, vmath.vector4(1, 1, 1, 1))
							gui.set_color(btn.stroke, vmath.vector4(1, 1, 1, 0))
						end)
						return true
					end
				end
			end
2 Likes

OMG! I read your message again and realized I missed this point:
main.gui_script: require "directory_with_button.button"

So now I understand how to use modules in gui. Thank you! It works well

1 Like

Oh, sorry I wrote it not so well formatted, but glad you figured! It’s a powerful stuff!