I copied the code from the GUI in 3D demo project which shows how to make a 2D UI with pickable elements within a 3D world. It almost works, except that there is a big discrepancy between where the elements are and where the mouse has to be to click them.
I’ve copied the settings and code exactly, aside from using my own 2D scene and enabling billboarding, so I’m not sure what the problem could be. The code accounts for billboarding settings and rotation, and I’ve changed the size of the scene/viewport/mesh around in the demo project to make sure that it doesn’t have an effect on it working. Does anyone familiar with this concept have any ideas for what I could look for?
I thought I might have to change the size or scaling options of the GUI scene that the viewport is displaying, but that doesn’t seem to have an effect when I change those in the demo project.
As a final test, I even dragged the scene from the demo project into my own project. I was surprised to see that the input is also off! So - what could be different about my 3D camera or scene that is causing pushing inputs to a SubViewport to be so off?
If you need a flat 2D scene on top of your 3D scene you don’t need to do anything special. No need for SubViewports or anything. Only if you need to have your 2D scene integrated in your 3D scene (for example, a monitor showing a fake desktop in your game) is when you need to follow what the 2D in 3D demo does.
The issue is probably that you enabled billboarding. Try posting more info like source code, scene structure,…
I was testing the scene from the GUI in 3D demo project on Github/the Asset library. The script I am using to push inputs to the SubViewport can be found here.. The code has functions for billboarding and for camera rotation, both of which function fine when running the test project itself.
I am familiar with using 2D in the 3D scene outside of the Viewport. There is a specific reason I wanted to use this particular menu as a gui that spawns in the 3d scene instead of a typical UI on the screen.
Here’s what the scene in my project looks like:
(removed photo)
Note that the collisionshape looks misaligned from the gui merely because billboarding is enabled. The shape appears to follow the camera when running.
I just can’t think of a reason why it would work in the test project but not in my project.
The one piece of code that I admittedly don’t fully understand is the section in which the coordinates are translated to that of the 2D scene to push it:
# convert the relative event position from 3D to 2D
var mouse_pos2D = Vector2(mouse_pos3D.x, -mouse_pos3D.y)
# Right now the event position's range is the following: (-quad_size/2) -> (quad_size/2)
# We need to convert it into the following range: 0 -> quad_size
mouse_pos2D.x += quad_mesh_size.x / 2
mouse_pos2D.y += quad_mesh_size.y / 2
# Then we need to convert it into the following range: 0 -> 1
mouse_pos2D.x = mouse_pos2D.x / quad_mesh_size.x
mouse_pos2D.y = mouse_pos2D.y / quad_mesh_size.y
# Finally, we convert the position to the following range: 0 -> viewport.size
mouse_pos2D.x = mouse_pos2D.x * node_viewport.size.x
mouse_pos2D.y = mouse_pos2D.y * node_viewport.size.y
# We need to do these conversions so the event's position is in the viewport's coordinate system.
# Set the event's position and global position.
event.position = mouse_pos2D
event.global_position = mouse_pos2D
I’ve found that when I comment out certain sections of this code, or even play with the numbers, it doesn’t change the behavior much at all.
Unless there’s an obvious fix to this that I’m missing, I was considering just trying to rebuild this on my own from scratch. Any tips in that direction would be helpful too.
You are right. I hopped on my computer to reply and accidentally pulled up the old demo.
I did see that comment. However, I found that billboarding worked fine when enabling in the test project. Perhaps there is some other issue which can present itself, but I’m still left wondering what could possibly be particular about my project that causes it to occur.
I appear to have solved this issue by simply merely removing the rotate_area_to_billboard() function from the script. Despite using billboarding, it now works as intended.