Animated sprite on canvas for gui not aligning consistenly

Godot Version

Godot 4.3

Question

Hello, so I am trying to attach an animated sprite of a health bar to my camera. Thats all I want to do and it sounds so incredibly simple but its behaving so chaotically completely beyond any control whatsoever. Pardon my french but “Je perds la putain tête”.

First I tried making the sprite a child of my camera, that didn’t work. So I added a canvas as a child of camera and made the sprite a child of that. This also did not work and the health bar simply stuck to the background. So then I added a control node under the canvas layer and stuck the sprite on the control node. This didn’t work so then I went back to the canvas and disabled it following viewport. This sort of helped. Now the health bar accurately follows my screen but for some reason instead of being on the bottom left of my screen its bound to a quarter scale rectangle bound to the top left of my screen. FYI the health bar is in the correct location in the 2D scene viewer but as soon as I hit play it becomes tiny and jumps to the wrong location. Again this seems so simple. I don’t understand why its so hard to use.

Please tell me there’s some simple thing I’m missing and I don’t have to write a whole page of code just to make an animated sprite follow a camera.

Thanks.

(Screenshots in order: tree view, game view, 2D editor view)
Screenshot 2024-11-20 215040


Put the canvas_layer as a child of the level_scene instead of the camera

Okay I did that but now it’s doing the exact same thing where is scales itself down and gives itself some huge offset but only while running. These are new pictures I just took of the editor window and the game.


I’ve spent hours trying to fix this and its driving me up the f*cking wall.

This is probably the simplest thing I could imagine doing on this engine I just want a sprite to stay put on my computer screen. Instead I’m getting routed through all these forums and advanced tutorials on using containers and all this other random stuff.

I’ve tried making the animated sprite a child of the scene, the player, the camera, a canvas layer, a canvas layer child of the camera/player/scene, a child of a container under everything I just mentioned, a node 2D under everything I just mentioned, the same thing but first with the container under the canvas layer in every above position, I’ve tried aspect ratio containers, panel containers, basic control nodes, and more. I’ve tried every single combination I just listed but with and without follow viewport enabled. I’ve tried switching the coordinates from position to offset, then I set them in the canvas layer instead. I’ve tried changing the layer orders.

What the f*ck does this game engine want? Do I need to sacrifice my firstborn child to make a blood pact with Juan Linietsky so he can laser engrave the health bar on my physical monitor to keep it in place? I’m sorry I’m losing my temper but I’ve watched 15 different tutorials and looked over 25 different forums along with tons of documentation.

Please don’t tell me this game engine is so broken that I need to manually offset and scale the sprite way off screen and huge so when it gets shrunken and offset its in the right place? I would have to keep randomly changing numbers and running my game over and over and over just to get an eyeballed approximation of the health bar being lined up.

As a review, I have an animated 2D sprite. I can either have it follow my camera properly or I can have it scaled the same and in the correct position. I cannot have both for some reason that alludes me. Please reference above pictures. I’m desperate for any ideas others can provide, please help me.

1 Like

I agree in the sentiment that I don’t really see the super powers the UI nodes give to Godot. I only see tutorials about how powerful it is and it drives me nuts every time I want to do something. I’m new to this too and I just don’t comprehend how something as simple as adding an image can be so complicated to make it look like I want.

Regardless of my rant, let’s try make it work.

If you add the CanvasLayer Node, you are making all its contents be above your “regular” game, so just for better order, you can put it as a child of the parent level itself as it will be independent.

Now, the first node you have is a Control one, you would like it to cover all the window size, so anything you add to it, stays inside that box.

This thing:
image

As you are using control nodes now for the UI, the rest or your nodes should also be of this type. For the health bar you would need to use a TextureRect node as a child of the Control node and add the sprite there. I know it’s not animated, but just try it like this for now and see if now it behaves as you want. Drag the TextureRect to the place in the viewport you want it to be.

If we can make it at least move like you want, we can work the the rest following that.

1 Like

Okay, for the record thanks so much.

So I tried that and had the same issue, I think I realized what might be the problem. I brute forced the alignment by scaling up the sprite and moving it way off screen I did this enough and checked back and forth by running the game 30 times and got it to render roughly in the right position/scale.

However, I think I now found the stem of my problem:

I discovered this faint blue rectangle which I think represents my viewport. The pink rectangle is of course my camera. I think what is happening is somehow my viewport is offset and over scaled and when I hit run its somehow resized/scaled to fit my camera or vice versa. Because now looking at the blue rectangle, the health bar is roughly in the same position of where I wanted it over the camera window. I’ve been trying to fix this but I don’t even know where to start. I’ve tried resizing the viewport but then it just scales down the camera and I cant offset the viewport to center on my player. I may be having a misunderstanding on the functionality of the viewport.

I think what you were saying is fully correct but its getting ruined by this anomaly I managed to setup.

I’ll Include my window settings, tree, and camera setup if that might help you see what I did wrong.


*Where the health bar is in the editor will show up on my screen in roughly the right position when I hit run.

Okay this must be the issue. So my camera zoom was at 3.6x making the camera size 320x180. Instead I set the camera scale to 1.0 and changed the viewport size to 320x180.


Now items placed on the screen remain at the proper scale. But if you can see in the picture, the viewport and camera are both the same size but not centered together. When I run this the health bar retains its scale but the viewport is still getting transformed onto the camera center and it pulls all the canvas layers with it.

I’ve tried multiple ways but no matter what I do I cannot center the viewport on the player/camera. This is still usable as I can offset HUD sprites by half the viewport width and length so that when I hit run its moved to the right spot. But this seems like such a lazy solution that will make things unnecessarily complex over time.

This whole time was I supposed to set up my camera/player starting out not at (0,0) but instead at the center of the viewport? That might make it so the canvas wouldn’t get displaced since it would already be aligned with the camera. Or maybe my viewport is required to be larger than my camera, I’m not sure.

You are on the correct track!

As you have discovered, the camera is the pink rectangle. By being the child of your player node, this makes the camera follow your player along, that is why the rectangle is centered around your player node, there is no need to make it match the viewport rectangle. You can check that if you change the Zoom, the pink rectangle will increase or decrease also.

I noticed the position values of your camera are not exactly at the center (0,-9), I think you would like to reset it to default and keep it perfectly centered.

Now, that viewport you also discovered, is the purple top, green on left and blue on right and bottom rectangle.This is the resolution of you game so you can have a reference point of how put things in place. Your CanvasLayer is a representation of that rectangle in a different layer, so the things you put it in must be inside this multicolor viewport rectangle. Since this is a different layer, your camera will ignore it an still keep moving with you player, leaving the canvas layer items in place and following along.

The Zoom of the camera should not change anything of the canvas layer, it will not scale. If you want the healthbar to look bigger, you will have to change that node scale relative to the viewport rectangle. Remember that changing the games resolution will also change the viewport size, and so the contents will look different in proportion.

Hope this helps to understand it a little better.

1 Like

Okay, so apparently I have the solution.

The trick is that camera zoom cannot be set at where you want it, that is exclusively reserved for momentary effects I suppose. You also cant spawn the player anywhere but it must start at the exact same global position based on your resolution.

Solution:

If you haven’t already, set your camera zoom to default of 1x on both directions. Then proceed into project settings > display > window > size, set the viewport width and height at the sizes you actually want your screen to be when played. This should rescale your camera for some f**king reason but because we set the camera to 1x scale it will be the same size as your viewport (the viewport will be a faint blue rectangle with the top left corner at the origin). The camera has a faint pink rectangle to show you its bounds.

Now you must drag your character with the camera child over until the camera and viewport rectangles are perfectly aligned. You can reposition the character and it does not have to be exactly in the middle coordinates of the viewport but the camera always must be.

Now if this works properly for you, the camera/viewport rectangle should actively represent your screen bounds. Add a canvas layer as a child of the overall scene (not the player) and make sure follow viewport is disabled. Anything you place as a child of that canvas layer that is also within the camera/viewport rectangle will remain fixed on your viewing screen and will not stupidly rescale themselves and warp across your screen when you load or when the player moves (including when position smoothing is enabled and the camera lags behind).

This was such a colossal pain to work out and I can’t believe the developers left such a gaping flaw in their platform where you need to design the level around a specific start position coordinate and cannot spawn the player anywhere else. I’ve gone through scores of tutorials and forums that lead me astray and somehow not a single starter tutorial said "remember to place your character with the camera top left corner at the origin or all HUD effects will be impossible to use. Even in the Brackey’s tutorial he specifically didn’t do this. That means even one of the most popular game developer teachers in the world did this wrong and is going to have trouble when he gets to his UI because this feature was just that astoundingly unintuitive. I’m going to post an image of all my other window settings that seem to work. If anyone has the same type of problem and this doesn’t work feel free to reach out but may whatever deity exists above have mercy on your soul, because the Godot devs won’t.