Menu
CoddyTech

ノードをコンポーネントとして扱う

CoddyのGDScriptジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 42/65。

一个 Node 可以有子节点。Godot 以这种方式构建游戏对象:一个英雄节点会为每种能力各添加一个子节点,例如生命值或移动能力。每个子节点都是一个组件:一个负责完成单项工作的简单节点。

# health.gd
class_name Health
extends Node

var hp := 10

func _ready() -> void:
	print("Health ready")

# hero.gd
class_name Hero
extends Node

func _init() -> void:
	var health := Health.new()
	health.name = "Health"
	add_child(health)

func _ready() -> void:
	print("Hero ready, hp: ", $Health.hp)

add_child()はノードを子として追加します。各コンポーネントにnameを付けます。get_node("Health")またはその短縮形の$Healthで、その名前の子を見つけられます。名前が付いていないノードや、兄弟ノードがすでにその名前を使用しているノードには、@Node@4のような自動名が付けられます。

ノードの_ready()は、ゲームが実行されているノードのツリーであるシーンツリーに入ると実行されます。main.gdはツリー内にあるため、ヒーローを追加すると、両方の_ready()メソッドが実行されます。まず子ノードのメソッドが実行されます:

# main.gd
var hero := Hero.new()
add_child(hero)            # Health の準備が完了し、次に Hero の準備が完了。hp: 10
print(hero.get_child_count())   # 1

親ノードは、get_children()(追加された順に並んだ子ノードの配列)、get_child_count()、およびhas_node("Health")を使ってコンポーネントにアクセスします。ツリー内のノードはゲーム終了時にツリーとともに解放されるため、add_child()で追加したコンポーネントをクリーンアップする必要はありません。

challenge icon

チャレンジ

簡単

コンポーネントノードからロボットを作りましょう。

  • Part は Node を継承します。コンストラクターはパーツ名とパワーの値を受け取り、パワーを保存し、ノードの name にパーツ名を設定します。パーツがシーンツリーに入ると、その _ready() は Laser attached を出力します。
  • Robot は Node を継承します。add_part(part_name, power) は新しい Part を子として追加します。ロボットがすでにその名前の子を持っている場合は、Laser is already attached を出力し、何も作成しません。
  • total_power() は、すべてのパーツのパワーの合計を返します。

提供されたコードはロボットをシーンツリーに追加し、後に続くコマンドの数を読み取り(add Laser 5、power)、最後にパーツの数を出力します。add Laser 5、add Wheels 2、power、add Laser 9、add Arm 3、power の場合、次のように出力します。

Laser attached
Wheels attached
Total power: 7
Laser is already attached
Arm attached
Total power: 10
Parts: 3

コードは part.gd と robot.gd に記述します。main.gd には提供された入出力コードがあり、編集できません。

自分で試してみよう

extends Node

func _ready():
	# 提供された入出力コード:そのままにしてください
	var robot := Robot.new()
	add_child(robot)
	var count := int(OS.read_string_from_stdin())
	for i in count:
		var parts := OS.read_string_from_stdin().split(" ")
		if parts[0] == "add":
			robot.add_part(parts[1], int(parts[2]))
		else:
			print("Total power: ", robot.total_power())
	print("Parts: ", robot.get_child_count())
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: GDScriptオンラインコンパイラ