【Godot 4.0】関数を次フレームに呼び出す方法

導入

関数を次フレームに呼び出す方法として、call_deferredがよく挙げられますが、誤った方法です。海外のコミュニティでも、「call_deferredを使えば良いよ!」という声しか無かったので、その誤解を解く為にこの記事を書きました。

方法

await get_tree().create_timer(0).timeout

を使う。このコードの意味は「シーンツリー上に0秒のタイマーを作成して、そのタイマーが切れるまで待つ」です。次フレームまで処理が中断されるので、このコードの後ろに実行したい関数をおけば良いです。

「0秒タイマー」によって丁度次フレームまで処理を中断させることができる理由は、タイマーの処理が各フレームの最初(自作スクリプトが実行される前)に行われるからです。

call_deferredのよくある誤解

call_deferredは「後で関数を呼ぶ」関数です。しかし、call_deferredによって指定された関数は次フレームに行く前に呼ばれてしまいます。例えば、あるフレームでcall_deferredを使って関数を呼んだ場合、同じフレームの_processの前に関数が呼ばれてしまうことがあります。

海外コミュニティにcall_deferredについての正確な動作を解説したポストがあります。

ここからかいつまんで説明すると、以下のようになります。

call_deferredはスタックに関数を入れますが、そのスタックの関数が実行されるタイミングは1フレームで複数回あります。コードの終わりなどにもそのタイミングがあるので、指定した関数が現フレームで呼ばれてしまいます。

Comment
byu/belzecue from discussion
ingodot

【GameMaker Studio 2】親オブジェクトの変数や関数を子オブジェクトで継承する方法

導入

オブジェクトの親オブジェクトを設定したとき、子オブジェクトの「Create」や「Step」は親オブジェクトと同じものに設定されます。

子オブジェクトの「Create」や「Step」を新たに作成すると、親オブジェクトの「Create」や「Step」は消えてしまい、変数や関数を継承できません。

じゃあどうすれば良いか?…その答えが見つかったので、それを共有したいと思います。

前提として

オブジェクトの「Parent」という欄でオブジェクトの親オブジェクトを設定することができます。

方法①(関数と変数を継承)

例えば「Create」に書かれている関数を継承したい場合、子オブジェクトに新しく「Create」を作り、その一行目に以下のコードを挿入する。

// 子オブジェクトの「Create」
event_perform_object(object_get_parent(object_index), ev_create, 0);

このコードは、親オブジェクトの「Create」を呼ぶコードです。このコードの下に処理を書いていけば、任意の変数や関数を変更することができます。

また、親オブジェクトの「Step」を呼びたいときは、ev_createをev_stepに変更すると良いです。

方法②(変数のみを継承)

親オブジェクトを開き、「VariableDefinition」を開きます。そして、「Name」 に変数の名前、「Type」に変数の型、「Default」に初期値を入れます。

次に、子オブジェクトの「VariableDefinition」を開き、変数の右にある「鉛筆マーク」をクリックすると、変数はオーバーライドされます。このとき、変数を初期値を独自に変更できるようになります。

また、オーバーライドを解除したいときは同じ場所を再度クリックすると良いです。