So first setup your nodes like so
Mesh Instance
-> Viewport
-> A GUI Node like Label

Then setup a new plane mesh, which you can resize by clicking on it to whatever you want the GUI size to be

Setup a script for the Mesh Instance
node
extends MeshInstance
onready var m_RadialBar = $GUI/RadialBar
func _ready():
yield(get_tree(), "idle_frame")
yield(get_tree(), "idle_frame")
var gui_img = $GUI.get_texture()
var material = SpatialMaterial.new()
material.flags_transparent = true
material.flags_unshaded = true
material.albedo_texture = gui_img
set_surface_material(0, material)
func Update(timeLeft, totalTime):
m_RadialBar.value = (timeLeft / totalTime) * 100
print(m_RadialBar.value)
Now setup your Viewport
to half the size of the image you want to use or text. In my case my Texture Progress
node uses a 64x64 image so I setup my Viewport
size to 32x32. If your text or image is off center on the mesh or really small and not as big as the mesh, fiddle with this setting. The idea is that the viewport renders the 2D image on the 3D mesh so this will affect your 2D image size when rendered.
Still in the Viewport
inspector, change:
- Size - Described above
- Transparent Bg - On
- Hdr - Off
- Usage - 2D No-Sampling
- V Flip - On

Finally add your GUI node/nodes (you can include control nodes I think)
Last but not least you need to setup a script somewhere else to call the Update
function from the Mesh script we made. I did this with a parent node by adding some script to it.
onready var m_RadialUI = $GUIInteraction
You can change GUIInteraction to the name of your Mesh Instance
node where the previous script is.
func _physics_process(delta):
m_RadialUI.Update($InteractTimer.get_time_left(), $InteractTimer.get_wait_time())
Add this function to call it every physics frame and then add the Update