How to fix a label. Not affect by camera zoom.

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

So many questions :).

I have a camera which is able to zoom in and out and i have a label which shows the amount of zoom. How can I prevent that the label is also getting zoomed.
I tried to use more nodes and nest everything in different ways but had no success so far.
Do i have to use a second camera with another viewport?

:bust_in_silhouette: Reply From: Alex\doc

Assuming you are in 2D (I never tried 3D before)
I would add a function to the camera to return the zoom amount:

func get_zoom_amount():
  return get_zoom();

then I’d make a new parallaxBackground, check ignore zoom add the label as child.

On the label, add a script to set the text using the get_node("camera").get_zoom_amount() change it basing on the hierarchy.

That worked. Thanks.

grol | 2016-03-23 22:44

Hi!

Would you be so kind as to share the code that made it work? I’m struggling with the exact same problem (in the Escoria framework) and help would be greatly appreciated!

I have tried both a CanvasLayer and a ParallaxBackground, but I don’t understand from the reply what “setting the text using” or “changing ‘it’” really means.

mjtorn | 2018-08-30 08:30

:bust_in_silhouette: Reply From: jospic

Put your label as child in a CanvasLayer

This blocks the position but not the zoom. Or did I miss something?

grol | 2016-03-23 22:39

No sorry. It also blocks the zoom. I only have to figure out what position it has relative to my viewport.

grol | 2016-03-24 07:44

I noticed this was posted after the comment that you got it to work.

This worked for me: gist:518598d2682725535c99feb0dfa77e9e · GitHub

In the context of Escoria: Implement dialog layer by mjtorn · Pull Request #224 · godot-escoria/escoria-demo-game · GitHub

Hope this is useful to someone facing the same problem!

mjtorn | 2018-08-31 12:49

:bust_in_silhouette: Reply From: TheNormandyProject

2023 | Godot 4 RC 1 | 2D

Please note that the following solution will “nudge” when hitting a collision layer.

With the accepted solution, and as of version stated above, you will have to deal with discrepancies between what you see on the editor and what’s displayed in game when you’re using “centered” textures for backgrounds, which is what I had to deal with. This is of course you’re happy setting endless offsets to get a consistent image, or adding a position : Transform2D adjustment to half your x and y. This is what I ended up doing.

I tried the following solution provided below, however the nudge was not intended behaviour in my eyes so I prefer dealing with the visual offset between editor and in-game. Please refer to the accepted answer for how to achieve the solution I ended up adopting.

I’ve left the following solution as an alternative and for the learning process.




This example is for a Clamped camera that cannot zoom out from 1 (into negative and flipped values).

Replace $node_type with the node used and replace $name with the name of the node.

  • Camera 2D
  • Parallax Background or CanvasLayer ($name)
    • Label or Control>Label

Enable Follow Viewport option in the CanvasLayer options in the editor.


Camera.gd

@onready var zoom_counter : $node_type = get_node(`$name`)
_process( delta ):
   zoom_counter.set_text( "Zoom: ", str(self.zoom()) ) // str method converts a given value to a string
   zoom_counter.follow_viewport_scale = 1 / self.zoom // self.get_zoom()
   // you can do the same with transform.origin to "pin" to a position, I can't get Parallax and CanvasLayer with ignore zoom and follow viewport to work correctly.

We use 1 / self.zoom value for the viewport scale due to as you zoom in the camera you want to match the zoom in the alternate direction for the Label. If you use a OneMinus operation then that’ll allow negative values which will flip the label’s Transform. 1 represents a 1:1 or Unity value, you want to get the relative percentage change applied to the follow_viewport_scale to keep the position in the same location. This is why the operation is like so.