🔖

[Godot] 一度に複数add_childを実行する方法

2024/02/13に公開

Godotでランタイム(実行時)にシーンツリーにノードを追加する場合、Node.add_child()を使いますが、同時に複数の子ノードを追加しようとすると

E 0:00:00:0701   hoge.gd:13 @ _ready(): Parent node is busy setting up children, `add_child()` failed. Consider using `add_child.call_deferred(child)` instead.
  <C++ Error>    Condition "data.blocked > 0" is true.
  <C++ Source>   scene/main/node.cpp:1415 @ add_child()
  <Stack Trace>  hoge.gd:13 @ _ready()

というエラーが出ます。
「親ノードが忙しいのに次の子ノードを追加するな。代わりにadd_child.call_deferred(child)を使ってね。」とおこられました。
call_deferredは「呼び出しを一旦待機して、次フレーム以降のアイドル時に実行する」(?)というメソッドだそうです。なのでいっぺんにadd_childせずに順次、子ノードを追加してくれるみたいです。

Gdscriptで記述すると以下のようになります。

func _ready():
   for i in range(10):
        var new_node:Node3D = preload("res://new_node.tscn").instantiate()
        new_node.name = new_node.name + "_" + str(i)
        # ↓間違い
        # get_parent().add_child(new_node)
        # ↓正しい
        get_parent().add_child.call_deferred(new_node)
        print("new_node: ", new_node.name)
		

Discussion