2D TextureProgress in a 3D space?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By CensedPie

I am looking for a way to setup something like the TextureProgress node in my 3D environment, perhaps with Sprite3D. The effect I want to achieve is a 2D radial bar in a 3D space which I can place in 3D. I don’t need it to billboard, just to be able to set it facing in a direction.

What should I be using to achieve this effect and can I use a TextureProgress node at all?

I’ve found a tutorial which doesn’t explain it that well but I managed to follow it,


It uses a mesh and then a viewport on the mesh to render 2D UI onto a mesh.

However now I am unsure how I can map the texture to spread across the whole mesh. In my instance the texture is set to the lower right of the mesh and I am unsure why.

EDIT: I had to set the viewport to render smaller. I will post my setup here in a bit.

CensedPie | 2018-12-13 07:47

:bust_in_silhouette: Reply From: CensedPie

So first setup your nodes like so
Mesh InstanceViewport → A GUI Node like Label
Scene Setup

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

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

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

Viewport setup

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

Why the viewport has to be half the size?

Oliver_sr | 2019-01-19 20:47