Quick answer: Pass a progress Array to load_threaded_get_status and read element 0. Await get_tree().process_frame between polls. Handle THREAD_LOAD_FAILED explicitly.
A loading screen uses ResourceLoader.load_threaded_request to fetch a big scene. The progress bar stays at 0%. Status checks return IN_PROGRESS indefinitely. The load eventually completes but progress never updates.
Two Common Issues
1. Progress not requested: load_threaded_get_status takes an optional Array parameter. Without it, you get status but no percentage.
2. Tight polling loop: if you call get_status in a while loop without yielding, the main thread blocks; the load thread can’t make progress, status stays IN_PROGRESS forever, your bar stays at 0%.
The Fix
func load_scene_threaded(path: String) -> Resource:
var err = ResourceLoader.load_threaded_request(path)
if err != OK:
push_error("load_threaded_request failed: %d" % err)
return null
var progress: Array = []
while true:
var status = ResourceLoader.load_threaded_get_status(path, progress)
$LoadingBar.value = progress[0] * 100
match status:
ResourceLoader.THREAD_LOAD_LOADED:
return ResourceLoader.load_threaded_get(path)
ResourceLoader.THREAD_LOAD_FAILED:
push_error("Load failed")
return null
ResourceLoader.THREAD_LOAD_INVALID_RESOURCE:
push_error("Invalid resource")
return null
await get_tree().process_frame # critical: yield to engine
The progress Array receives [0.0..1.0]. The await yields back to the engine each frame, letting the load thread make progress and the UI refresh.
Status Codes to Handle
- THREAD_LOAD_IN_PROGRESS: still loading.
- THREAD_LOAD_LOADED: done. Call load_threaded_get to retrieve.
- THREAD_LOAD_FAILED: load failed mid-stream (corrupted file, missing dependency).
- THREAD_LOAD_INVALID_RESOURCE: the request was never accepted (bad path).
Always branch on all four. Ignoring FAILED produces infinite spinners on bad inputs.
Sub-Resource Progress
For large scenes that reference many sub-resources, the progress reflects sub-resource discovery in stages, not strictly linear. Expect the bar to jump (e.g., 0.1 to 0.7 in a moment) as the load resolves child resources.
Verifying
Load a known-good scene. The progress bar should climb smoothly to 1.0 over the load duration. Loading a known-corrupt resource should produce THREAD_LOAD_FAILED quickly with your error path firing.
“Pass the progress array. Yield between polls. Handle all four status codes. Threaded loading just works.”
For scene transitions, run threaded loads while a fade-out animation plays — player perceives zero wait when timed right.