Godot4 GDスクリプトからの動的なノードの生成・初期化・削除

2D / 3D ゲームを作成できる無料・オープンソースの軽快なゲームエンジン「Godot Engine 4」で、作成したシーンを、子ノードとして GD スクリプトで動的に生成、メンバ変数の設定、シーンへの配置削除の手順を紹介します。

※この記事の内容は、アプリ タップ The 宝箱 の開発でも使用しています。
※ GodotEngine のバージョンは 4.1.2 です。 .NET 版ではありません

※記事で紹介するスクリプト / プログラム / コードは自己責任で使用してください。

前回の記事

前回は「Godot Engine 4」で、最初から使える Tween 機能を使って、円の大きさをなめらかに変化させました。

ripple シーンをスクリプト内で生成・メンバ変数の設定

章末の GameManger.gd スクリプトの一部を説明しながら、スクリプトで子ノードを作成する手順を紹介します。

4 行目で sceneRipple メンバ変数を定義しています。
9 行目で sceneRipple メンバ変数は ripple シーンのファイル ripple.tscn を preload 関数で読み込みPackedScene を格納します。
これにより ripple シーンを子ノードとして作成する準備ができました。

Godot4 シーンファイルを preload します.

クリックイベントは、左マウスボタンを離した瞬間としました。
21 行目から始まる _input イベント関数で、マウスの左ボタンが離されたかを調べて、クリックしたかどうかを判定します。

その判定の後の 33 行目で、先ほど読み込んでおいた sceneRipplePackedScene.instantiate メンバ関数を呼び出して、スクリプトの中で ripple 子ノードを動的に作成します。

34 行目では、作成した ripple 子ノードの位置を表す position 変数に、マウスの位置を設定して初期化しています。

作成した ripple 子ノードの初期化を行ったら、36 行目で add_child 関数に ripple 子ノードを渡して、game_manager シーンに追加します。

これにより ripple 子ノードはクリックされた座標に配置されて、そこを中心にした波紋のアニメーションを描画します。

extends Node

# 波紋を描画するシーンを子ノードとして生成する際に用います。
var sceneRipple

# Called when the node enters the scene tree for the first time.
func _ready():
	# Ripple ノードを生成するために必要な ripple シーンを読み込んでおきます。
	sceneRipple = preload("res://ripple.tscn")
	return


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
	pass

# ドラッグ中ならば true です。 _input イベントで扱います。
var dragging = false

# 入力イベントが発生するたびに呼び出されるイベント関数です。
func _input(event):
	# 入力の例 — Godot Engine (4.x)の日本語のドキュメント - https://docs.godotengine.org/ja/4.x/tutorials/inputs/input_examples.html#mouse-motion
	if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT:
		# Start dragging if the click is on the sprite.
		if not dragging and event.pressed:
			dragging = true
			# 左ボタンを押した瞬間の処理
		# Stop dragging if the button is released.
		if dragging and not event.pressed:
			dragging = false
			# ボタンを離した瞬間の処理
			# 波紋シーンの生成と配置
			var nodeRipple = sceneRipple.instantiate()
			nodeRipple.center = event.position # 描画する中心座標にクリックした位置を設定します。
			add_child(nodeRipple) # シーンに子ノードとして追加します。
	# While dragging, move the sprite with the mouse.
	if event is InputEventMouseMotion and dragging:
		# ドラッグ中の処理
		pass
	return

ripple 子ノードの削除

動的に作成した ripple 子ノードは、波紋のアニメーションが完了したら削除します。
子ノードの削除は、 ripple 子ノード自身が行います。

前回紹介した Ripple.gd の Tween による処理の後に、 Tween による値の遷移が完了した後に、処理を再開して自身のノードを消去する処理を追加しました。
※ 33 ~ 34 行目に追加しただけで、他は前回紹介したスクリプトと同じです。

33 行目で await を使い、 Tween による半径の変化が完了した後にその後の処理を再開します。
処理を再開した時点ですでに波紋のように円が拡大するアニメーションは完了しています。
34 行目で自身のノードを削除するために queue_free メンバ関数を呼び出します。

extends Node2D

# 描画する円の半径です。時間経過で変化します。
var radius = 3
# 描画する円の中心座標です。
var center = Vector2(320, 240)
# radius メンバ変数の値を指定した時間で変化させる際に使用します。
var tween

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

# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
	# 毎フレームごとノードの再描画を要求して、 _draw イベント関数を呼び出させます。
	queue_redraw()

# radius を tween によって少しずつ変化させます。
func animation_ripple():
	# Tween を生成します。
	tween = get_tree().create_tween()
	# Tween で変化させる対象の変数の初期値を設定します。
	radius = 3
	# Tween で徐々に変化させるパラメータを設定して、変化を開始します。
	tween.tween_property(
		self,             # 自分自身を登録
		"radius",       # positionパラメータを制御
		60, 		# 変化後の値
		1,                # 1秒間で変化
	)
	await tween.finished # tween が完了したら処理を再開します。
	queue_free()	# 自身のノードを消去します。
	return 
	

# _draw() 関数は一度だけ呼び出され、その後は描画コマンドがキャッシュされて記憶されるため、それ以上の呼び出しは不要です。
# 再描画が必要な場合は CanvasItem.queue_redraw() を呼び出してください。
func _draw():
	# 色の変数に白色を設定します。
	var white : Color = Color.WHITE
	# 円を指定した座標を中心に、指定した半径と指定した色で描画します。
	#sc_draw_circle(center, radius, white)
	#draw_arc(center, radius, 0.0, 360.0, 60, white, 3, true)
	sc_draw_arc(center, radius, 0.0, 360.0, white, 3, true)
	return

# 円弧を描画します。 draw_arc 関数の point_count (頂点数) を自動計算して呼び出します。
# center : 中心の座標
# radius : 半径
# start_angle, end_angle : 円弧の開始と終了の角度
# color : 色
# width : 線の太さ
# antiariased : アンチエイリアスの有無. 詳しくは CanvasItem — Godot Engine (4.x)の日本語のドキュメント - https://docs.godotengine.org/ja/4.x/classes/class_canvasitem.html#class-canvasitem-method-draw-arc
func sc_draw_arc(center, radius, start_angle, end_angle, color, width, antialiased):
	# 円周(2*PI+r)の距離に比例した個数の頂点を結ぶ線分で円を描画します。
	# 試した結果、円周÷6 の頂点数だとあまり角が目立たないと思いました。
	var numof_points = ceili(2 * PI * radius / 6)
	# 円周が短く、頂点数が 12 個より小さい場合は角が目立つので 12 に補正します。
	if numof_points < 12:
		numof_points = 12
	print("radius = ", radius, ", numof_points = ", numof_points)
	draw_arc(center, radius, 0.0, 360.0, numof_points, color, width, true)
	return

テスト

game_manager シーンを開いて、 F6 キーでシーンを再生しましょう。
ウィンドウのクライアント領域をクリックすると、その場所に ripple ノードが配置されて、波紋のアニメーションが表示されました。

Godot4 Ripple子ノードをクリック時に GameManager のスクリプトから動的に生成して波紋のアニメーションを表示した例

まとめ

今回は 2D / 3D ゲームを作成できる無料・オープンソースの軽快なゲームエンジン「Godot Engine 4」で、作成したシーンを、子ノードとして GD スクリプトで動的に生成、メンバ変数の設定、シーンへの配置削除の手順を紹介しました。
クリック時のイベント処理を _input イベント関数で行うスクリプトも紹介しました。

参照サイト 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をコピーしました