🏃
【Godot Engine】シーンチェンジ先のシーンに引数を渡す その2
はじめに
SceneTree.change_scene()でシーンを変更する時は、変更先のシーンに引数を渡せません。
前回は、AutoLoadを使用して擬似的に引数を渡す方法を紹介しましたが、グローバル変数を使っているのが個人的に好みではなかったので他の方法を探してきました。
今回はRelayクラスを作って変数を中継する方法を紹介します。
方法
UseRelayNode.gd
extends Node2D
@onready var Line = $LineEdit
func _on_button_pressed():
var relay = Relay.new_relay(Line.text)
var packed = PackedScene.new()
packed.pack(relay)
get_tree().change_scene_to_packed(packed)
Relay.gd
extends Node
class_name Relay
@export var text:String
static func new_relay(text:String) -> Relay:
var relay = Relay.new()
relay.text = text
return relay
func _ready() -> void:
var scene_file:PackedScene = load("res://UseRelayNode/NewScene.tscn")
var scene_node = scene_file.instantiate()
scene_node.text = text
get_tree().root.add_child(scene_node)
free()
NewScene.gd
extends Node2D
@onready var label = $Label
var text:String
func _ready() -> void:
label.text = text
このコードでは、MainシーンのButtonを押下した時、
LineEdit.textの値をRelay.gd経由でNewScene.gdに渡しています。
Relay.gdのstatic func new_relay(text:String)にてインスタンスを作成していますが、_init(text:String)を作って同様のことをしようとすると次のようなエラーが発生し、シーンチェンジ先のRelayに値を渡せなくなります。
error
E 0:00:04:0069 UseRelayNode.gd:9 @ _on_button_pressed(): Error constructing a GDScriptInstance: 'Node(Relay.gd)::_init': Method expected 1 arguments, but called with 0
<C++ エラー> Method/function failed. Returning: nullptr
<C++ ソース> modules/gdscript/gdscript.cpp:196 @ _create_instance()
<スタックトレース> UseRelayNode.gd:9 @ _on_button_pressed()
RelayはなくてもOK
NewScene.gdのtextに@exportをつけ、ボタンの挙動を次の実装にすると、Relayを噛ませなくても直接シーンチェンジすることはできます。
NotUseRelayNode.gd
extends Node2D
@onready var Line = $LineEdit
func _on_button_pressed():
extends Node2D
@onready var Line = $LineEdit
func _on_button_pressed():
var scene_file:PackedScene = load("res://UseRelayNode/NewScene.tscn")
var scene_node = scene_file.instantiate()
scene_node.text = Line.text
var packed = PackedScene.new()
packed.pack(scene_node)
get_tree().change_scene_to_packed(packed)
ただ、移動先のシーンが大きい場合PackedSceneをinstantiate()した上でPack()し直す挙動で無駄にメモリを使っていそうな気がする(測ってない)ので基本はRelayを使い、移行先のファイルが小さいなら直接シーンチェンジするのが良いと思います。
Discussion