• 2D
  • Make HUD textures unaffected by Light 2D

Hi all, I am working on a prototype for a simple 2d action rpg with WSAD controls and camera rotating about the player (like a 3D fps but stripped of the vertical dimension, hence of of the vertical mouse motion). I added a Light2D child to the player node, and occlusion shapes to tilemap walls and enemies sprites. Now I am adding a HUD (with health/stamina bars), as a Control node child of the Camera2D node (which is child of the player node):

My problem is that the health bar texture is affected by the Light2D node, but also by the occlusion shadows drawn by the tilemap walls:

I tried to play both with the "Light Mask" Layers and the z Index of the sprites involved, but I suspect there is something fundamental wrong in what I am doing and would really appreciate some advice, of any kind because right now I feel like a monkey just randomly pressing buttons.

edit: grammar

As silly as it may sound: I did not know viewport could be used in this way, thank you for the link to your example. Now I added my whole scene to the viewport and added the HUD as a Control Node working together. Now I have many other problems, for example the Scene inside the viewport not reacting to unhandled_input(event) but only to input(event). Moreover the FPS have dropped from ~55 to something around 25 now that the game scene works inside the viewport. Anyway, your answer helped me a lot, thank you!

I have not used it much myself, but you might be able to use a CanvasLayer instead of a Viewport. That will place the UI on it's own layer, which should make it just draw on top of whatever is on the screen. Due to the UI being drawn on top of the screen, if you use a CanvasLayer you will still likely need to reduce/remove the alpha on the health bar so the dark sections of the screen do not effect the visibility of the health bar.


As for the viewport and _unhandled_input, how are you displaying the texture from the Viewport? It could be the node you are using for displaying the Viewport is catching the input events.

If you are trying to process Mouse events in _unhandled_input and you are displaying the Viewport through a Control-based node, you can tell the mouse events to be passed by changing the Mouse Filter property on the Control-based node. If you set it to ignore, mouse events on that node will be ignored and should be able to be processed through _unhandled_input.

If you are trying to process Keyboard events _unhandled_input, then you'll probably need to pass events captured by the Control-based node to the Viewport. How you do this though, I have no idea. You might be able to pass events by overriding the gui_event function, but I have not done this myself so I don't know if it will work or not.

On the Viewport, you might be able to increase performance by changing the usage (documentation) property to either 2D or 2D no sampling, depending on the needs of your project. Likewise, you probably want to set the disable_3d property to true. With those settings enabled, the Viewport node shouldn't attempt to initialize itself for 3D and run 3D related code. Without the 3D side of the Viewport enabled, performance should be a little better.

If you need 3D nodes for your UI, the only thing I can think of that might improve performance is to lower/disable MSAA on the Viewport and see if that helps. You could also try setting the usage to 3D No Effects and see if that helps.

Also note that one can always lower a viewports resolution if need be(thus still able to have crisp native res GUI and just the games resolution lowering), though generally speaking unless dealing with really low-end hardware I don't think it should really significantly affect performance.

But then, I haven't really run godot on anything weaker than Intel HD 4000, and even on that particular system I have an additional nvidia GT 750m graphics chip that I typically use for godot instead. So my experience might be a bit skewed. Also, I never target nor develop for mobile, so, no experience on that front.