0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Godot4.1で遭遇した諸々のメモ

Last updated at Posted at 2023-10-03

Godot4.1(正確には4.1.1)で遭遇したお作法なのか不具合なのかわからない事象のメモ。

なんかシーンファイルが壊れる

https://github.com/godotengine/godot/issues/64330
事象としてはこれっぽい。
調べた感じだと、後述のpreloadによる循環参照にも関係あるっぽい模様。

preloadを使って循環参照すると、instantiateしたノードのスクリプトが空になる

https://github.com/godotengine/godot/issues/76641
経緯としては以下の感じ。

  1. エディタを開きなおすと時折シーンが壊れて読み込めなくなる(開きなおす前にファイルをいじってはいない)。
  2. 閉じる前にファイルを開いておいて、エディタを閉じた際に勝手にファイルが更新されないことも確認(=ファイルそれ自体の問題ではない)
  3. 継承シーンの問題かとも思った(もともと継承シーンが読み込めなくなっていた)が、複製したシーンでも発生。
  4. とりあえず究明は置いといて動作確認を進めてたら、なんかinstantiateしたオブジェクトのスクリプトが空になっていることが判明。
  5. エディタ起動時にエラーメッセージが出てたのに気づいたのでぐぐる。結果、どうもpreloadにバグがあるっぽいと判明。
  6. URL先を読んだ感じ、どうもpreloadというかUIDキャッシュ周りにそもそも問題があるっぽ。

なので、問題の大本はどうも一緒っぽいと思いつつ、解決されるまでは循環参照をしないコードにするしかないかなあ。

子から親の処理を呼ぶ方法

色々ある(autoloadにしたりとか)ようだけど、emit_signal飛ばしてやるのがよさそう。

まず、子にシグナルの定義とemit_signal(シグナル発火)を書く。
シグナルに引数も持たせられる(複数個も可)。

child.gd
signal fire(arg1, arg2)

func _ready():
    emit_signal("fire", 1, 2)

親で呼びたい関数を作り、connectで接続する。
子ノードがすでに存在しているなら${子ノード}.connectで直接connectすればいい。
instantiateしたノードなら、add_childの直前(直後でもいいらしいけど、自分はいまのところ直前派)にconnectしてやる。
子ノード指定でconnectしてないと、親がシグナル拾ってこれないので注意。

parent.gd
var child_scene = preload("res://scenes/child.tscn")

func _fire(arg1, arg2):
    print(arg1)
    print(arg2)

func _ready():
    # 存在する子ノードを使うケース
    $child.connect("fire", Callable(self, "_fire")) # すでに存在する子ノードのシグナルを拾う

    # 新たにinstantiateした子ノードを使うケース
    var child = child_scene.instantiate() # 子ノードをinstantiate

    child.connect("fire", Callable(self, "_fire")) # 子ノードのシグナルと接続
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?