Menu
CoddyTech

시그널에 연결하기

Coddy GDScript 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 65개 중 37번째.

connect()는 실행할 함수를 Callable로 받습니다. 괄호 없이 메서드 이름을 쓰거나 람다를 작성하세요:

chest.opened.connect(_on_chest_opened)          # 이 스크립트의 메서드
chest.opened.connect(quest_log.add_entry)       # 다른 객체의 메서드
chest.opened.connect(func(): print("Creak!"))   # 람다 함수

Godot에서는 수신 메서드의 이름을 _on_, 그다음에는 신호를 보내는 대상, 마지막으로 신호를 나타내는 순서로 지정합니다. 예를 들면 _on_chest_opened입니다. 하나의 신호에 여러 함수를 연결할 수 있으며, 이 함수들은 연결된 순서대로 실행됩니다.

리스너 객체는 일반적으로 이미터를 전달받는 메서드에서 직접 연결합니다:

# quest_log.gd
class_name QuestLog
extends RefCounted

var chests_opened := 0

func track(chest: Chest) -> void:
	if not chest.opened.is_connected(_on_chest_opened):
		chest.opened.connect(_on_chest_opened)

func untrack(chest: Chest) -> void:
	if chest.opened.is_connected(_on_chest_opened):
		chest.opened.disconnect(_on_chest_opened)

func _on_chest_opened() -> void:
	chests_opened += 1

같은 함수를 같은 신호에 두 번 연결하는 것은 오류이며, 연결되어 있지 않은 함수를 연결 해제하는 것도 오류입니다. is_connected()가 먼저 확인합니다. disconnect()는 수신을 중지하며, 다음 신호 발생 시 해당 함수는 더 이상 실행되지 않습니다.

두 번째 인수로 CONNECT_ONE_SHOT을 전달하면 연결은 첫 호출 후 자동으로 해제됩니다: chest.opened.connect(_on_first_open, CONNECT_ONE_SHOT).

람다는 생성될 당시 지역 변수에 저장되어 있던 값을 유지합니다. 연결된 람다 안의 count += 1은 그 복사본을 변경하며, _ready()의 count는 0으로 유지됩니다. QuestLog처럼 리스너 객체의 멤버 변수에 카운터를 보관하세요.

challenge icon

챌린지

쉬움
hit를 내보내는 표적이 있습니다. 표적의 신호를 수신하는 ScoreBoard를 작성하세요:

  • watch(target)는 표적의 hit 신호를 _on_target_hit에 연결합니다. 이미 감시 중인 표적을 감시해도 아무것도 바뀌지 않습니다.
  • ignore(target)는 연결을 해제합니다. 감시 중이 아닌 표적을 무시해도 아무것도 바뀌지 않습니다.
  • _on_target_hit()는 points에 10을 더하고 Hit! Score: N을 출력합니다.
target.gd는 완성되어 있습니다.

watch 0, ignore 0, shoot 0 같은 명령을 읽고 최종 점수를 출력합니다. 표적이 두 개이고 명령이 watch 0, shoot 0, shoot 1, watch 1, watch 1, shoot 1, ignore 0, shoot 0일 때 출력은 다음과 같습니다:

Shot target 0
Hit! Score: 10
Shot target 1
Shot target 1
Hit! Score: 20
Shot target 0
Final score: 20
score_board.gd와 target.gd에 작성하세요. main.gd에는 제공된 입출력 코드가 있으며 수정할 수 없습니다.

직접 해보기

extends Node

func _ready():
	# 제공된 입출력 코드: 그대로 두세요
	var board := ScoreBoard.new()
	var targets: Array[Target] = []
	for i in int(OS.read_string_from_stdin()):
		targets.append(Target.new())
	var count := int(OS.read_string_from_stdin())
	for i in count:
		var parts := OS.read_string_from_stdin().split(" ")
		var target := targets[int(parts[1])]
		if parts[0] == "watch":
			board.watch(target)
		elif parts[0] == "ignore":
			board.ignore(target)
		else:
			print("Shot target ", parts[1])
			target.shoot()
	print("Final score: ", board.points)
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 GDScript 컴파일러