公式サイトはこちら / 公式ドキュメント(Godot 4) / 公式ドキュメント(Godot 3) / 当サイトのGodot記事一覧はこちら
今日はGodotの「onready」キーワードについて調べます。
クラスの変数定義を見ると、
var a = 10
onready var a = 10
と、onreadyキーワードを付けているもの、付けていないものがあります。これは何を意味しているのでしょうか?
ちなみに2番目の onready var a = 10
は、実はonreadyを付ける意味はありません。以下の記事に使い方と理由を書きました。(おまじないのように全てにonreadyを付けている人がいましたので、解説します)
onreadyはシーンの _ready を再現するもの
Godotの特長として、ツリーオブジェクトは上から下へアクティブ化されます。これをまず押さえてください。
たとえばノードが以下の構成になっていたとします。
トップのNode2Dにスクリプトをアタッチし、コードを以下のように書いたとします。
var n = $Label
すると、実行時にエラーになります。(書いた時点ですでに警告が出ますが)
なぜかというと、Node2Dのクラス変数が初期化される時点では、まだLabelノードが実体化していないため、その存在を n に代入することができないのです。
冒頭に書いたとおり、ツリーオブジェクトは上から下へアクティブ化され、加えてスクリプトのクラス変数は、アクティブ化と同時に実行されます。Labelの実体化はこのあとになります。
Node2Dのスクリプトが実行される時点では、Labelはまだ単なる定義にすぎないのです。
そうなると、n に代入できるのはシーン全体が実体化(インスタンス化)したあと。つまり func _ready()
が動くときになります。
正しく書くと以下のようになります。
var n
func _ready():
n = $Label
これは正しく動き、nにはLabelの実体が代入されます。
さて、今回は n がたった1つなのでいいのですが、このような処理をしたい変数が5個、10個とたくさんあったらどうでしょうか?
全部を var 定義し、その代入を _ready() に書くとなるとコード量がかなり増えますし、変数を加えたり削除したりするたびに _ready() 内も編集しなければなりません。
ここでようやっと onready キーワードになります。
onready を付けた変数は、上記の _ready() と同じ動きを再現してくれるのです。
つまり
onready var n = $Label
と書くことができます。これは正しく動きます。
このコードが実行されるときにはまだ Label は実体化していませんが、Godotが暗黙的に実行を遅らせてくれ、ツリーが生成し終わったときに改めて代入してくれるのです!
たくさんの代入定義があっても、定義のみを書き換えれば済みます。定義は1行に収まるので、コードも見やすく、編集しやすくなるのです。
意味のない onready
onready var a = 10
改めて冒頭のコードです。
onreadyの意味が分かれば、これが無意味なコードだということもわかりますね。
a には整数10を代入しているだけで、10はツリーオブジェクトではありません。つまりいつ呼び出してもまったくかまわないのです。試しにonreadyを削除しても、問題なく実行できます。
全てのクラス変数にonreadyを付ける必要はありません。
コメント