Scene freezing after loading

Godot Version

Godot-4

Question

I have a really simple 2d game, zelda1-like movement, tilemapped, really super basic.

I’m running into an issue where the game freezes immediately after loading the main scene from the menu. like the scene appears, all the graphics are there, but the input is locked and animations don’t play.

Here’s the incredibly simple functioning code of the main menu:

if Input.is_key_pressed(KEY_SPACE):
			get_tree().change_scene_to_file("res://Scenes/LoadingScrene.tscn")

that’s in the process function.

does anyone know why this happens? I’ve tried a loading screen as well and that doesn’t seem to help so I think it’s an issue on the end of the main scene. It’s not a very complicated scene, all the sprites and tiles are less than 32x32px and the map is pretty small. what’s happening?

1 Like

Are you pausing the game with get_tree().paused = true?

Are you pausing the game with Engine.time_scale = 0.0? Then, don’t do that. Use the get_tree().paused = true method.

More info here Pausing games and process mode — Godot Engine (stable) documentation in English

1 Like

i tested the code here

there’s nothing wrong with changing scene to file method, and using KEY_SPACE, doesnt double input it, if it does then it should show error of null value, but it didnt, it loaded in your end

so it should be something wrong in your main scene script
show your mainscript if possible

There isn’t a script controlling the main scene, it’s just logic for the player and enemies. Here’s the player script:

I apologize if it’s a little sloppy, I’m not great at Godot yet

extends CharacterBody2D

@export var walkSpeed = 10
@export var sprintSpeed = 60
@onready var animations =$AnimationPlayer
@export var keyUI = Label
@export var levelKeyUI = Label

var Sprinting = false
var sprintCool = false

var moveLock = false

var direction = "walkright"
var dead = false
var keys = 0
var levelKey = false

func _ready():
	updateAnimation()

func handleInput():
	var moveDir = Input.get_vector("ui_left","ui_right", "ui_up", "ui_down")
	
	if Input.is_action_just_pressed("Sprint") && sprintCool == false:
		$Timer.wait_time = 3
		$Timer.start()
		
		Sprinting = true
	
	if Sprinting == false:
		velocity = moveDir * walkSpeed
	else:
		velocity = moveDir * sprintSpeed
	
	
func updateAnimation():
	if velocity.length() == 0: 
		direction = "Idle"

	else:
		if velocity.y > 0 : 
			direction = "walkdown" 

		elif velocity.y < 0 : 
			direction = "walkup"

		if velocity.x < 0 : 
			direction = "walkleft" 

		elif velocity.x > 0 : 
			direction = "walkright"

	
	
	if dead: direction = "Dead"
	animations.play(direction)
	
func _physics_process(delta):
	keyUI.text = (str(keys)+" keys")
	
	if levelKey == false:
		levelKeyUI.text = "..."
	else:
		levelKeyUI.text = "Get Out"
		
	updateAnimation() 
	if !dead && !moveLock: 
		move_and_slide()
		handleInput()





func _on_area_2d_area_entered(area):
	if area.get_parent().name.contains("Tripod"):
		dead = true
		get_tree().change_scene_to_file("res://Scenes/Dead.tscn")
	if area.get_parent().name.contains("Key"):
		keys += 1
		area.get_parent().queue_free()
		
	if area.get_parent().name.contains("LevelKee"):
		levelKey = true
		area.get_parent().queue_free()
		
	if area.get_parent().name.contains("Door"):
		if keys > 0:
			keys -= 1
			area.get_parent().queue_free()
			
	if area.get_parent().name.contains("BigD"):
		if levelKey == true:
			area.get_parent().queue_free()
	if area.get_parent().name.contains("Stairs"):
		moveLock = true
		direction = "Idle"




func _on_video_stream_player_finished():
	moveLock = false;



func _on_timer_timeout():
	Sprinting = false
	sprintCool = true
	$coolDown.start()



func _on_cool_down_timeout():
	sprintCool = false
1 Like

I should also mention, it’s only frozen for a few seconds after loading, like it has to buffer or something

it probably just not “gapless” scene change, as the godot needs to build from scratch for the new scene after removing all the previous one
the solution for this is to manually change the scene with remove and add child

while changing it tho, show a loading screen so it doesnt look like there’s grey scene before changing scene

above solution code is just a snippet, you will want to integrate it to fit your needs, but it didnt use change_scene_to_file method for changing scene

the loading panel can be on TopUI Layer (different and higher layer than basic UI CanvasLayer) that will show when triggered on changing scene