Godot4 preload したスクリプトをシーンのノードに割り当てる実装例

ゲームエンジン GodotEngine4 で、シーンに配置されているノードに動的にスクリプトを割り当てることができる set_script 関数を用いて、実行中に動的にスクリプトを割り当てて動作させる実装例実行結果を紹介します。
例として、ラベルノードに、実行開始後にスクリプトを割り当てて、そのスクリプトの処理によって経過時間を表示させます。

※ GodotEngine 4.3 を使用しています。.NET 版ではありません。
※スクリプトは自己責任でご使用ください。

前回の記事

前回は、class_name で定義したグローバルクラス名とそのスクリプト内の GDScript オブジェクトの静的変数名の組み合わせで、疑似的な名前空間のようなアクセスの仕方で静的関数を呼び出しました。

Object クラスの set_script 関数

シーンのノードに、スクリプトを動的に割り当てるには、シーンのノードset_script メンバ関数を呼び出し、割り当てたいスクリプトリソース(例では GDScript )のオブジェクトを引数で指定します。

Attaches script to the object, and instantiates it. As a result, the script’s _init() is called. A Script is used to extend the object’s functionality.

If a script already exists, its instance is detached, and its property values and state are lost. Built-in property values are still kept.

スクリプトをオブジェクトにアタッチし、インスタンス化します。その結果、スクリプトの _init() が呼び出されます。スクリプトは、オブジェクトの機能を拡張するために使用されます。

スクリプトがすでに存在する場合、そのインスタンスは切り離され、そのプロパティ値と状態は失われます。組み込みのプロパティ値は引き続き保持されます。

Object — Godot Engine (stable) documentation in English #set_script と Google 翻訳

実装例

以下は、シーンの Label ノードに set_script 関数を用いて動的に割り当てる .gd スクリプトです。

ラベルのテキストに、経過時間を毎フレーム表示します。
※小数点1桁までの文字列を作成するフォーマットについては、「GDScriptフォーマット文字列 — Godot Engine (4.x)の日本語のドキュメント」を参照してください。

extends Label

## シーン開始時から計測される経過時間です。
var elapsed_time: float = 0.0

func _init():
	print("_init called")
	return

# Called when the node enters the scene tree for the first time.
func _ready():
	print("_ready called")
	return

# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta):
	# 経過時間を更新して、ラベルの表示に反映します。
	elapsed_time += _delta
	update_text()
	return

## ラベルの text プロパティに、
## 小数1桁までの経過時間 [member elapsed_time] の文字列を設定します。
func update_text() -> void:
	self.text = "%.1f" % elapsed_time
	return

上記のスクリプトを以下のスクリプトで preload 関数で読み込み、GDScript リソースのオブジェクトとして静的変数に格納して、外部からアクセスできるようにします。
※ class_name でグローバルクラス名を設定しているので、外部からそのクラス名を用いてアクセスできます。

extends Object
class_name MySubmodule

## class_name で定義したグローバルクラスの名前と組み合わせて、
## 各スクリプトの静的関数を呼び出すための変数を提供します。
const V1 := preload("../submodule_v1/my_submodule.gd")
const V2 := preload("../submodule_v2/my_submodule.gd")

## シーンのノードに割り当てるスクリプトを GDScript オブジェクトとして静的変数に読み込みます。
const LabelElapsedTime := preload("../label_elapsed_time.gd")

スクリプトを動的に割り当てる Label ノードを持つシーン(ルートノードは Control クラス) を作成します。

  • PseudoNamespaceWithPreload (Control)
    • LabelElapsedTime (Label)

シーンでは、Label ノードに、スクリプトを割り当てません。

Godot4 preload したスクリプトをシーンのノードに割り当てる実装例2

作成したシーンのルートノード(Control クラス)に、以下のスクリプトを割り当てます。

11 ~ 14 行目で、 Label ノードにスクリプトを割り当て、そのスクリプトの _process イベント関数が呼び出されるように状態を変更しています。
set_process に関しては、次回の記事を参照してください。

extends Node

# preload と class_name による疑似的な名前空間のテスト用のコードです。
# 同じフォルダにある同じ名前のシーンファイルを選択して F6 キーなどで起動すると実行されます。

# Called when the node enters the scene tree for the first time.
func _ready():
	# グローバルクラスでバージョンの異なる静的関数を呼び出します。
	MySubmodule.V1.greet()  # Hello. Ver.1
	MySubmodule.V2.greet()  # Hello. Ver.2
	# preload で読み込まれた GDScript オブジェクトを、シーンのノードに割り当てます。
	$LabelElapsedTime.set_script(MySubmodule.LabelElapsedTime) 
	# ノードのプロセスを有効にして _process を毎フレーム呼び出します。
	$LabelElapsedTime.set_process(true)
	return

このスクリプトの _ready 関数内で、スクリプトが割り当てられていないラベルのノード(LabelElapsedTime)に、先ほど preload 関数で読み込んだ、GDScript スクリプトリソースのオブジェクトを set_script 関数で割り当てます。

実行結果

先ほどのシーンをシーンドックで開いた状態 F6 キーを押して実行すると、シーン上ではスクリプトを割り当てられていない Label ノードに、動的にスクリプトが割り当てられ、経過時間が毎フレーム表示されました。

Godot4 preload したスクリプトをシーンのノードに割り当てる実装例1

まとめ

  • set_script 関数を用いて、シーンに配置されたノードに、実行中にスクリプトを動的に割り当てることができました。
  • スクリプトpreload 関数で、GDScript などのスクリプトリソースのオブジェクトとして変数で扱えます。
  • class_name でグローバルクラスを定義したファイル内で、スクリプトリソースを静的変数に格納することで、外部からクラス名と変数名を指定してアクセスできます。

参照サイト Thank You!

記事一覧 → Compota-Soft-Press

コメント

Ads Blocker Image Powered by Code Help Pro

お願い - Ads Blocker Detected

このサイトは広告を掲載して運営しています。

ポップアップを閉じて閲覧できますが、よろしければ

このサイト内の広告を非表示にする拡張機能をオフにしていただけませんか?

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

We have detected that you are using extensions to block ads. Please support us by disabling these ads blocker.

タイトルとURLをコピーしました