How to load a scene from a filepath

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

I have a TileMap saved as a scene for each level of my game, at the file path res://Maps/levelname/TileMap.tscn. I need to instance this correct TileMap under my root node, which hosts everything else that makes the game work. I have tried both of the following variations of code to achieve this with a test map:

var next_map
var loading_map


if File.new().file_exists("res://Maps/testencounter/TileMap.tscn"):
    next_map = load("res://Maps/testencounter/TileMap.tscn")
    loading_map = next_map.instance()
    add_child(loading_map)
else:
    pass

&

if ResourceLoader.exists("res://Maps/testencounter/TileMap.tscn"):
    next_map = ResourceLoader.load("res://Maps/testencounter/TileMap.tscn")
    loading_map = next_map.instance()
    add_child(loading_map)
else:
    pass

Both of these pieces of code simply pass, or print error if I replace pass with print(“error”). If I remove the if statement, they throw errors about being unable to open the specified file, and failing to load the resource. To see if anything could access the file, I replaced all code with

get_tree().change_scene("aforementioned path")

Right on queue, the scene changed from the root scene to the TileMap.

My question is: What am I doing wrong, and what is the right way to do what I’m trying to?

:bust_in_silhouette: Reply From: sash-rc

First some generic advice:

  1. Don’t use variables in outer scope, if you don’t use them in outer scope. Make them local.
  2. Don’t clone constant literals (strings) by copy-paste. This method is prone to errors. Use dedicated identifier for this.
  3. Use debug tools. From simple print() to breakpoints, scene-tree (called Remote tree) and variables inspectors. This way you will know what’s exactly happening under the hood.

Your approach is basically correct, but the errors tells you don’t have a file “Maps/testencounter/TileMap.tscn” in your project tree. For your case I’d use something like this:

func load_scene(var path, var parent : Node) -> Node:
  var result : Node = null
  if ResourceLoader.exists(path) :
    result = ResourceLoader.load(path).instance()
    if result :
      parent.add_child(result)
  return result
# ---
var scene_file : String = "res://path/file.tscn"
if ! load_scene(scene_file, self) :
  print("Error loading scene ", scene_file)