🔖

【Godot 4.x】Threadで引数を使う方法

2024/04/10に公開

thread.start(method)に引数を入れたい

前置き

GodotにはThreadと呼ばれる機能があります。
メインスレッドだけでは重くなる処理を並行してやらせたいときに、Threadが役立ちます。

引数が設定されているメソッドを、Threadで処理を行うとします。
以下は3*3の2次元配列を作り、その中でスレッドを立てて「ok」を出力するプログラムです。
ついでにarrayの中も出力してます。

var array;

# Called when the node enters the scene tree for the first time.
func _ready():
	array = make_2d_array();
	print(array);

#2次元配列を作る
func make_2d_array():
	var arr = [];
	for i in 3:
		arr.append([]);
		for j in 3:
			var td : Thread = Thread.new();
			td.start(test);
			arr[i].append(td);
	return arr;
				
#テスト出力用メソッド
func test():
	print("ok");

func test2(x,y):
	print(x,y);

#スレッドのクローズ処理
func _exit_tree():
	for i in array.size():
		for j in array[i].size():
			array[i][j].wait_to_finish();

#(文末の「;」は、Unity時代からの名残として私が勝手に付けてるだけです;;)

結果


ちゃんと結果が出ましたね。okです。

本題

では、threadの内容をtest2メソッドのものにしたいので、make_2d_array()を以下に書き換えます。

func make_2d_array():
	var arr = [];
	for i in 3:
		arr.append([]);
		for j in 3:
			var td : Thread = Thread.new();
			td.start(test2(i,j));
			arr[i].append(td);
	return arr;

書き換えたうえで、実行してみます。

結果


何か出た。「引数 1 を Nil から Callable に変換できないよ~!」って言われてますね。引数1はNil(nullと同義)ではなく、int型を入れたはず。そもそもCallableってなんだ...
...任意の型に変換する前に、Callableに変換しろってことなのでしょうか。

.bind()で解決

調べてみたところ、以下のサイト(https://github.com/godotengine/godot-proposals/issues/4691) では「.bind()に引数入れると良いよ」みたいなことが書いてありました。
その情報をもとに、make_2d_array()を以下に書き換えます。

#2次元配列を作る
func make_2d_array():
	var arr = [];
	for i in 3:
		arr.append([]);
		for j in 3:
			var td : Thread = Thread.new();
			td.start(test2.bind(i,j));
			arr[i].append(td);
	return arr;
				

結果


おお~!通りました。これでthread経由でもメソッドに引数を入れて使うことが出来るようになりましたね。

参考文献

https://github.com/godotengine/godot-proposals/issues/4691

Discussion