Menu
CoddyTech

シグナルとは?

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

ゲームの実行中、オブジェクトにはさまざまなことが起こります。コインが集められたり、ドアが開いたり、ヒーローのhpが0に下がったりします。プログラムのほかの部分はこうしたイベントに反応します。スコアが上がり、効果音が鳴り、ゲームオーバー画面が表示されます。

シグナルとは、オブジェクトに何かが起きたときに、そのオブジェクトが送るメッセージです。オブジェクトがシグナルを発信すると、そのシグナルに接続されているすべての関数が実行されます。

# coin.gd
class_name Coin
extends RefCounted

signal collected

func collect() -> void:
	print("Coin picked up")
	collected.emit()

signal collectedでシグナルを宣言し、collected.emit()で送信します。コインは誰がリッスンしているか知りません。コインに関係するコードは、自身の関数の1つをシグナルに接続します。

# main.gd
func _ready():
	var coin := Coin.new()
	coin.collected.connect(_on_coin_collected)
	coin.collect()
	print("Done")

func _on_coin_collected() -> void:
	print("Score +1")

出力はCoin picked up、Score +1、Doneです。シグナルを発信すると、emit()の次の行に進む前に、接続された関数がすぐに実行されます。接続された関数がないシグナルは、発信しても何も起こりません。

シグナルがなければ、collect()はスコアのコードを自分で呼び出す必要があるため、すべてのコインがスコアボードへの参照を持つ必要があります。シグナルがあれば、コインはイベントを通知するだけで、任意の数のリスナーが反応できますし、リスナーがいなくてもかまいません。

Godot独自のノードも同じように動作します。Buttonはクリックされるとpressedを発し、Timerは時間切れになるとtimeoutを発します。

challenge icon

チャレンジ

簡単

メールボックスはシグナルで新着メールを知らせます。Mailbox にはすでに signal mail_arrived が宣言されており、letters カウンターがあります。deliver(kind) を記述してください。

  • kind が "letter" の場合、letters に 1 を加算し、mail_arrived を発行します。
  • それ以外の種類(広告やチラシ)は捨てられます。何も変更されず、何も発行されません。

提供されたコードは You've got mail! を出力する関数を接続し、その後、続く行数を読み取って各行の配達を処理します。away の行はその関数の接続を解除し、home の行は再び接続します。そのため、留守中に届いた手紙はカウントされますが、通知されません。letter、ad、away、letter の各行に対して、次のように出力します。

Delivering: letter
You've got mail!
Delivering: ad
Delivering: letter
Letters: 2

コードは mailbox.gd に記述してください。main.gd には提供された入出力コードがあり、編集できません。

自分で試してみよう

extends Node

func _ready():
	# 提供された入出力コード: そのままにしてください
	var mailbox := Mailbox.new()
	mailbox.mail_arrived.connect(_on_mail_arrived)
	var count := int(OS.read_string_from_stdin())
	for i in count:
		var line := OS.read_string_from_stdin()
		if line == "away":
			mailbox.mail_arrived.disconnect(_on_mail_arrived)
		elif line == "home":
			mailbox.mail_arrived.connect(_on_mail_arrived)
		else:
			print("Delivering: ", line)
			mailbox.deliver(line)
	print("Letters: ", mailbox.letters)

func _on_mail_arrived() -> void:
	print("You've got mail!")
quiz icon腕試し

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

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

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