Godot Engine エラー "get_tree: Condition "!data.tree" is true. Returned: nullptr" の対処について

# はじめに
PeanutsCodeさんのプラットフォーマー制作でGodotを学習中。
[前回がPart8](https://qiita.com/gmasa/items/23c4a16cd6dcba34db42)、今回はPart9。連続で何かしら発生してます。

# 環境
- Windows版 Godot Engine Ver.3.5(stable)
- GDScript

# 現象
[プラットフォーマー制作Part9](https://www.peanuts-code.com/ja/tutorials/gd0005_platformer/platformer_9/)において、ゲームオーバー画面から、Restart / Quit を実行すると下記エラーが発生。実行は続く。

```text: error
get_tree: Condition "!data.tree" is true. Returned: nullptr
scene/main/node.h:*** @ get_tree()
Game.gd:** @ change_level()
```

下記コードの `get_tree()` が原因。ルートの Game ノードがないのに `get_tree()` を実行して怒られていると予想。
```gdscript
func change_level():
	if get_tree():
		print("change_level() called.")
		if current_level < final_level:
			print("change to next level.")
			level.queue_free()
		# 中略
```


# ボツ案

`get_tree()` がダメなら `is_instance_valid()` でいけるかやってみたところ、

```gdscript
func change_level():
	if !is_instance_valid($"/root/Game"):	# 追記
		return								# 追記
	if get_tree():
		print("change_level() called.")
		if current_level < final_level:
			print("change to next level.")
			level.queue_free()

		# 中略
```

エラー。。
```text: error
get_node_or_null: Can't use get_node() with absolute paths from outside the active scene tree.
get_node_or_null: アクティブなシーンツリーの外側から絶対パスで get_node() を使用することはできません。

get_path: Cannot get path of node as it is not in a scene tree.
get_path: シーンツリー内にないため、ノードのパスを取得できません。

get_node: (Node not found: "/root/Game" (absolute path attempted from "").
get_node: (ノードが見つかりませんでした。"/root/Game" (絶対パスが "" から試行されました).

get_tree: Condition "!data.tree" is true. Returned: nullptr
get_tree。条件 "!data.tree" は真です。戻り値：nullptr
```


# 解決策

上記のボツ案のエラーメッセージにある、『アクティブなシーンツリーの外側から絶対パスで get_node() を使用することはできません。』をヒントに、`change_level` を呼び出すシグナルとして `tree_exited` 以外に相応しいものがないのか探した。
すると、すぐ下に `tree_exiting` なるシグナルがあった！
早速修正してみる。（上のボツ案で追加した２行は削除しておく。）

```gdscript
func add_level():
	level = load("res://Levels/Level" + str(current_level) + ".tscn").instance()
	# 旧：level.connect("tree_exited", self, "change_level")
	level.connect("tree_exiting", self, "change_level")	# 変更箇所
	add_child(level)
	player = level.get_node("Player")
	player.connect("player_damaged", self, "_on_Player_player_damaged")
	player.connect("item_hit", self, "_on_Player_item_hit")
```

表題のエラーは消えたが、以下のエラーが発生。

```text: error
add_child: Parent node is busy setting up children, add_node() failed. Consider using call_deferred("add_child", child) instead.
add_child: 親ノードが子供の設定に追われているため、add_node()は失敗しました。代わりにcall_deferred("add_child", child)を使用することを検討してください。
```

「call_deferred godot」等でググった後『うん、なんとなくわかりました:relaxed:』と納得した上で、エラーメッセージの通り以下の修正を加えた。
```gdscript
func add_level():
	level = load("res://Levels/Level" + str(current_level) + ".tscn").instance()
	level.connect("tree_exiting", self, "change_level")
	# 旧: add_child(level)
	call_deferred("add_child", level)	# 変更箇所
	player = level.get_node("Player")
	player.connect("player_damaged", self, "_on_Player_player_damaged")
	player.connect("item_hit", self, "_on_Player_item_hit")
```

エラーが消えた！！



# 最後に
本当はボツ案に記した内容の前に、別の方法を試しました。
お手本の方法（Restart時にGame.gbを破棄して読み直す方法）を採用しない形を考えて作業を進めてみたのです。できないことは無さそうでしたが、かなりゴチャつきそうだったので、素直にお手本の方法のままエラー除去する方法を探すことにしたのです。

`is_instance_valid` を見つけて『これでいける！』と思ったところにエラー吐かれてガックリしましたが、諦めなければ何とかなるものです。

こんなことで一苦労しているのは自分だけでしょうか。
地道にがんばります。:walking_tone1: