Use GO/sprite instead of GUI as button?


Is it possible to make a GO/sprite act like button without using GUI methods? can GUI scripts be attached to GOs/Sprites the same way they are added to GUIs?

(and I just wanna put a cookie here as a thanks to all the amazing people in this community that put up with me and probably many other users asking basic questions and helping me to learn and use defold, you are the reason I’m here :smiley:)(special shoutout to britzl for being the lord and saviour of thousands of people in so many ways)



Hahah! Thanks!

I believe @sergey.lerg uses game objects for all of his UI elements.

1 Like


Hi grify!

GOs use GO scripts, but yes, they can do everything a GUI node can do and more. I used GOs for everything until I learned about the GUI node system and some of the advantages it has.

I achieved this by using a collision object in the GO that worked as a button, and having another GO object that followed the mouse, and detecting collisions. However, it would actually be easier to do it by detecting the position of the mouse within the GO button’s script.

However… can we ask if there is some reason you don’t want to use GUI nodes? They really are very convenient for buttons and you’re going to end up doing a lot of “reinventing the wheel” coding.

1 Like


I’ve recently switched to the collision object GO approach and it made my life a lot easier in the end, and the code a lot neater.

It might be that I wasn’t using GUI to its full potential, but it seems to me to be good at some simple menus, but when most of your game consists of verious menus and dialogs that need to be generated dynamically, doing it through GO’s makes more sense.



@grify Yes, I have quite complex UI all implemented with just GO. The principle is simple:

  1. Use orthographic projection that matches screen size.
  2. Create rectangles using quad model and factory.
  3. Add rectangles to a table, sorted by z.
  4. On touch input traverse the table and calculate if the touch x,y is inside the topmost rectangle or continue until found on.
  5. When found, invoke touch function attached to the rectangle.

All my rects don’t have scripts inside their GO, just the model component. I use a single script file for the entire scene and use Lua modules for independent components like button, scroll view, dialogs, settings sidebar, etc.



It’s weird because I’m currently re-making bikiniverse (play at ) using only GUI stuff so i’m having the opposite revelation to all of you. In my case I just like the look of it and the way they automatically fit any screen size. I also had such a bloated project that had gone on so long, I’ve been able to recreate 80% of what I had in just a few days.

I’ve also done away with update functions (though I think I will need my first one soon), collisions,
different collections, and sprites (can’t wait to share my new art style with you guys).



It might be that remaking stuff from scratch tends to lead to cleaner code in general, no matter if you use GUI or GOs. I know it is like that for me.

1 Like


Hello Josh!
I want to use GOs as nodes for custom and strangely shaped hitboxes on my buttons, so I can animate the GUIs in unison with the rest of the GOs, and so I can easily render the buttons amongst the rest of the GOs without a noticeable difference in graphics.

I don’t currently know any methods to accomplish these with GUI nodes without tampering with the renderscript, and creating an extensive amount of GUI nodes programmatically, and I honestly don’t know how to make them render similarly, without the GUI overlapping the GOs always, so this seemed like the best approach.
Feel free to correct me on this if there is a tool that makes these easily accomplishable, or if I’ve overlooked something, and let me just say that I like the way you think.

Have a nice day!



Would you mind elaborating more on the reasons you switched to GOs, how difficult the switch was, and how you did it?

1 Like


Agreed, it allows for only the necessary bits of code to be where they are

Wouldn’t using only GUIs limit your capabilities in terms of animation? Do you manually write animations?

That seems to be the efficient way to do it, but I still find update functions as an easy way of ‘telling he time’. Mostly, I just use them for organizing loading screens.

I’m not entirely certain how to do step 1, but the rest is very logical. Does the have a projection mode or do you mean that I have to lock window size?

This seems very efficient, do you use any GUI nodes at all or just GOs even for the sidebar?



I mean tweaking the render script to match the size of orthographic projection matrix to the size of the window. This way one unit in game object coordinates becomes one pixel.

Not a single GUI node.

1 Like


@grify the orphographic projection stuff is going to be somewhat complicated (whereas with GUI more of it is automatic) but you’ll be okay.

I’ll be looking at it later because I want to automatically render some shadows and there’s a link to the material stuff, which I think is how I will do it.



No, because I was very bad at animating in GO anyway. Haha. And yes, I do all the animations manually with go.animate() (and particle.fx which are amazing and I love)

Actually, there’s a few things that I can do with GUI that i can’t do with GO in terms of animation (playing with scale, rotation, and size of shapes without aliasing, as well as clipping, and a few options with the pie node that I absolutely love). But it fits in with my new art style. Can’t wait to share some stuff

1 Like


This is very simple, it’s how the default render script works already.

-- render GUI
-- ...
render.set_projection(vmath.matrix4_orthographic(0, render.get_window_width(), 0, render.get_window_height(), -1, 1))
-- ...

vmath.matrix4_orthographic( left,right,bottom,top,near,far) just defines a 3D box. When you use it to set the projection, that means everything inside that box will be rendered. All you have to do is tweak the numbers.

In this case, render.get_window_width() and render.get_window_height() get the current width/height of the window. You could also use render.get_width() and render.get_height() to get the fixed width/height from your game.project settings. (Though that means it may get stretched if the window proportion changes.)



How do you tweak it? Isn’t it 1px/1unit by default?


I see, thanks! Good luck with your game!

Personally, I need my things to be aliased, as I’m using pixelart. Best of luck to you, and I can’t wait to check out what you’re working on!

Thank you very much! You are very helpful!