Fixing a Godot Editor Hang: health_bar_3d.tscn

How we removed a major editor slowdown caused by duplicate viewport rendering and always-on editor updates.

Godot Version: 4.x
Area: 3D UI / Health Bar
Symptoms: Editor hangs or becomes very slow when scenes/health_bar_3d.tscn is present/instanced

The Problem

The editor became sluggish as soon as scenes/health_bar_3d.tscn was used.
Changing unrelated nodes could take a long time to reload.

At first glance, the scene looked simple. The issue was hidden in how it rendered:

  1. It contained two viewport-based health bar pipelines at the same time (one legacy, one active).
  2. The script ran as @tool, so update logic executed in the editor continuously.
  3. The viewport used UPDATE_ALWAYS, forcing constant redraw even when nothing changed.

Combined, that created expensive editor-time work every frame.

Root Cause

scenes/health_bar_3d.tscn had two separate render chains:

  • Sprite3D/SubViewport/ProgressBar (legacy path)
  • BillboardSprite/Viewport/UI/ProgressBar (active path used by script)

And scenes/health_bar_3d.gd had:

  • @tool (runs in editor)
  • _viewport.render_target_update_mode = SubViewport.UPDATE_ALWAYS

That meant the scene was doing redundant viewport rendering and editor-time processing even when idle.

The Fix

1) Remove the duplicate legacy viewport path

In scenes/health_bar_3d.tscn, we removed:

  • Sprite3D
  • Sprite3D/SubViewport
  • Sprite3D/SubViewport/ProgressBar
  • related subresources (ViewportTexture_8v4abCanvasItemMaterial_8v4ab)

Now the scene has one rendering path only:

  • BillboardSprite + Viewport + UI/ProgressBar

2) Stop continuous viewport redraws

In scenes/health_bar_3d.gd:

  • Changed UPDATE_ALWAYS to UPDATE_ONCE.
  • Added _queue_viewport_redraw() and call it only when visuals change.
_viewport.render_target_update_mode = SubViewport.UPDATE_ONCE

func _queue_viewport_redraw() -> void:
	if not _viewport:
		return
	_viewport.render_target_update_mode = SubViewport.UPDATE_ONCE

3) Disable editor-time script execution

In scenes/health_bar_3d.gd:

  • Removed @tool.

This prevents per-frame health bar behavior from running in the editor while you are editing scenes.

Files Changed

  • scenes/health_bar_3d.tscn
  • scenes/health_bar_3d.gd

Why This Works

  • One viewport pipeline instead of two cuts redundant rendering work.
  • UPDATE_ONCE redraws only when needed, not every frame.
  • Removing @tool keeps runtime behavior out of editor idle loops.

Together, these changes remove the main sources of editor stalls while keeping the in-game health bar functionality.

Practical Rule for Future Godot UI

If a UI element uses SubViewport:

  1. Keep a single render path.
  2. Prefer UPDATE_ONCE (or disabled) over UPDATE_ALWAYS.
  3. Use @tool only when editor-time behavior is truly required.

These three checks prevent most viewport-related editor slowdowns.


Posted

in

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *