I’m fairly new to godot but have been having a good time, that is when I’m not hitting very obnoxious hurdles!
Hello, I’m having trouble today with camera zooming and overall UI problems, The items are inside of a canvaslayer.
I’m frankly having all sorts of weird troubles, one being where an area element inside the canvas layer displays correctly when at the origin but is not detecting the areas where it “should be”, it only detects the areas in the proper location when offset a seemingly arbitrary number of pixels. That same element doesn’t seem to be scaling with the canvas layer either but its hard to tell when the debug collision shape isn’t where the actual area is being detected.
I would very happily upload my project here for you to take a closer look.
So, little update here. I’ve managed to solve all but one issue, but this one is the most puzzling.
My area2d is a child of a canvas layer, and with debug detect collision objects on, I see the area staying in the correct position relative to my camera, but the actual area that is detecting signals is static and is not moving with my camera. Has anyone experienced this or does anyone have any advice?
I’m not sure the etiquette for doing so, but I would love to!
In my world scene I have a control node with a canvas layer child, this is the scaling layer. As a child of that canvas layer I have an area 2d with a collision shape (rectangle).
I also have a camera in the world scene.
I have a script attached to the control node which tells the scaling canvas layer to adjusts its scale in accordance with the camera’s.zoom.
As I mentioned before, with debug collision shapes on, the area does follow the camera around the screen and resize correctly, but the area itself does not seem to follow in that my mouse entering the area only activates it in its original “static” position, moving the camera will not move the activation area.
edit: if theres a normal method you guys use for sharing I would happily upload my project for clarification
Yeah, you can link your github repo, google drive, or whatever is reliable and easy to share. If you can condense the MRE to a single text based file, you could throw it up on something like pastebin.
Okay cool. I’m kinda new to this stuff so im unfamiliar with github, and only use google drive as cloud storage, so i’m unfamiliar with how i’d share it with you on there.
Great, I have downloaded your project. I can’t tell where the issue is and I’m not exactly sure what I should be seeing.
It helps a lot to create a Minimal, Reproducible Example. Start with an empty project and recreate the setup that causes the issue. Refrain from copy and pasting (within reason). Creating the MRE may give yourself a deeper insight into what’s wrong. The resulting MRE is easier for others to grok the issue.
I can try to provide an MRE in a day or so. In the meantime, if my program successfully loads for you, feel free to give this a try.
You can drag hold M1 and drag a box to select the drone unit (center screen), and then issue a build command somewhere.
The “UI Area” node contains a vertical and horizontal area which are for all intents and purposes the UI bounding box, within this area, some commands shouldn’t be capable of being executed, such as starting a construction of a building.
Right after starting the program, if you move your mouse to the left / top most portions of your screen, you should see it say “unable to build”, which is great. But if you move this area stays there statically. Now if you reset the X,Y position of the UI area box to 0,0, you’ll see the UI Area following the screen, visually (through debug collision shapes). However the actual area is not where it is being displayed, as hovering your mouse over the left mouse portion of the screen will trigger the area to say “unable to build”.
Thanks for expanding on that. I think I see what’s going on.
The issue
CanvasLayer only affects drawing. It’s like having layers of projector sheets. You can draw independently on each sheet, move them around, and see it projected as if there were only one sheet.
Now in your “ScalingLayer” you have a physics object child, the “UI Area”. Physics are decoupled from drawing. The shape visuals are only for us humans.
So, you have the “UI Area” visuals on it’s own sheet, but the actual physics is still in world space.
Notes
You should not scale physics objects. See this comment. It’s best to default to changing the collision shape’s size rather than scaling the physics object.
Only collisions between objects within the same canvas (Viewport canvas or CanvasLayer) are supported. The behavior of collisions between objects in different canvases is undefined.
Suggestions
I highly recommend using Control nodes for your UI instead of Area2Ds. You will run into more headaches later on.
Try ordering your scene tree before adding more canvas layers. For example, you could have your “UI” node be a CanvasLayer, then remove the “ScalingLayer” and “BuildButton”'s canvas layer, then move BuildButton to the end.
Move gameplay objects such as “VisibleUnitsArea” out of your “UI” tree.
If you have a script on a node that reaches up through the parent, like on your camera script, you should move that code up the scene tree or use node groups or signals. It will be cleaner and better for the long term.
I have been gone for a couple days due to irl stuff, but I appreciate your thorough response. I’m going to attempt to try the things you recommended, and will get back to you. Thank you!
I’m not sure how to set up the control nodes to perform the same function as my area nodes did. I’m also unsure how to better improve the code per your last suggestion about node groups and signals or moving it up the scene tree.
This will click in time. Right now it’s food for thought and making progress on your game is more important. You can read about Best Practices in the manual.
I think I’ve worked it out, I didn’t realize control nodes had “mouse entered / exited” as a signal / method, which is why I was using the area nodes originally. I think I’ve managed to work out the correct way to go about it. I created 2 control nodes as children of the canvas layer, one being the vertical bounder the other the horizontal bounding box, if the mouse enters one of these regions it sets a boolean Flag, inUIBoundingBox = true, and then I think i can restrict certain inputs and commands based on this flag.
Thank you.
If i have any more questions is it cool if I just dump them in this thread? Or is that against forum policy
Check out Node._unhandled_input(), too. A rule of thumb is _unhandled_input() is for gameplay input, _gui_input() is for, uh, ui. Read more about how controls handle input here.
I’d say if it’s a new question, create a new post. Easier to search and find for posterity.