본문 바로가기
Programming/Godot

Godot 엔진 시작하기 - Signal

by Wilkyway 2022. 1. 12.
반응형

Signal

소개

Signal은 옵저버 패턴의 Godot버전입니다. 특정 이벤트가 발생하면 노드는 신호를 보낼 수도 있고, 다른 노드는 그 신호에 응답할 수도 있습니다. 예로, 버튼이 눌려 있는지 매 프레임마다 확인하는 대신 버튼이 눌렸을 때 Signal을 보낼 수 있습니다. 

 

타이머 예

Timer 노드를 이용한 예제를 살펴보겠습니다. Node2D와 두 개의 자식(Timer 및 Sprite )이 있는 새 씬을 만듭니다 . 씬독에서 Node2D의 이름은 TimerExample로 바겠습니다.

Sprite의 텍스처에는 LoadSprite의 Texture 속성 드롭다운 메뉴에서 Godot 아이콘이나 원하는 다른 이미지를 할당합니다. 루트 노드에 스크립트를 첨부하되 아직 코드를 추가하지 마십시오.

씬 트리는 아래와 같이 구성합니다.

Timer 노드의 속성에서 자동 시작 옆에 있는 "켜기" 상자를 선택합니다 . 그러면 씬을 실행할 때 타이머가 자동으로 시작됩니다. 대기 시간 을 1초로 합니다.

Inspector 탭 옆에는 Node 탭이 있습니다. 이 탭을 클릭하면 선택한 노드가 내보낼 수 있는 신호 리스트를 볼 수 있습니다. Timer 노드의 경우 우리가 관심을 가져야할 것은 "timeout" Signal입니다. 이 Signal은 타이머가 0에 도달할 때마다 방출됩니다.

"timeout()" 신호를 클릭하고 신호 패널 하단의 "연결..."을 클릭합니다. 신호 연결 방법을 정의할 수 있는 다음 창이 표시됩니다.

왼쪽에서 씬의 노드를 볼 수 있으며 신호를 "수신"하려는 노드를 선택할 수 있습니다. Timer 노드는 파란색이며 이는 신호를 방출하는 노드임을 시각적으로 나타냅니다. 루트 노드를 선택합니다.

[주의] Signal수신하려는 노드에는 스크립트가 부착되어 있어야 하며 그렇지 않으면 오류 메시지가 표시됩니다.

고급 메뉴를 토글하면 오른쪽에 인수(다른 타입, 임의의 갯수)를 바인딩할 수 있는 것을 볼 수 있습니다. 

창 하단에는 "Receiver Method"이라는 필드가 있습니다. 이것은 사용하려는 대상 노드의 스크립트에 있는 함수의 이름입니다. 기본적으로 Godot는 _on_<노드이름>_<Signal이름> 의 명명 규칙으로 자동 생성 하지만 원하는 경우 변경할 수 있습니다.

"연결"을 클릭하면 스크립트에 함수가 생성됩니다.

extends Node2D


func _on_Timer_timeout():
    pass # Replace with function body.

이제 자동 생성된 코드를 신호가 수신될 때 실행하려는 코드로 바꿀 수 있습니다. Sprite를 깜박이도록 합시다.

extends Node2D


func _on_Timer_timeout():
    # Note: `$`는 `get_node()`의 단축형,
    # `$Sprite`는 `get_node("Sprite")`와 동일 의미.
    $Sprite.visible = !$Sprite.visible

씬을 실행하면 Sprite가 1초마다 깜박이는 것을 볼 수 있습니다. 타이머의 대기 시간 속성을 변경하여 깜빡임 속도를 변경할 수 있습니다.

코드에서 신호 연결

편집기가 아닌 코드에서 신호 연결을 만들 수도 있습니다. 이것은 일반적으로 코드를 통해 노드를 인스턴싱 할 때와 같이 편집기를 사용할 수 없을 때 필요합니다.

먼저 타이머의 "노드" 탭에서 연결을 선택하고 연결 해제를 클릭하여 신호를 연결 해제합니다.

코드에서 연결하기 위해 connect함수를 사용합니다. 실행하면 타이머가 자동 실행되도록 _ready() 함수에 입력하겠습니다 . 함수의 구문은

<노드>.connect(<signal이름>, <대상노드>, <대상함수이름>)

입니다 . 다음은 타이머 연결을 위한 코드입니다.

extends Node2D


func _ready():
    $Timer.connect("timeout", self, "_on_Timer_timeout")


func _on_Timer_timeout():
    $Sprite.visible = !$Sprite.visible

Custom Signal

Godot에서는 직접 생성한 커스텀 시그널을 선언을 사용할 수도 있습니다.

extends Node2D


signal my_signal

일단 선언되면 Custom Signal이 Inspector에 나타나며 다른 Signal과 같은 방식으로 연결할 수 있습니다.

코드를 통해 신호를 내보내려면 다음 emit_signal기능을 사용하세요.

extends Node2D


signal my_signal


func _ready():
    emit_signal("my_signal")

Signal 선언 시 하나 이상의 인수를 선언할 수도 있습니다. 괄호 사이에 인수 이름을 지정합니다.

extends Node


signal my_signal(value, other_value)

메모

Signal의 인수는 에디터의 노드 독에 표시되며, Godot는 이를 사용하여 콜백 함수를 생성합니다. 그러나 신호를 방출할 때 여전히 인수의 갯수를 변경할 수 있습니다. 따라서 올바른 값을 내보내는 것은 사용자에게 달려 있습니다.

값을 전달하려면 emit_signal함수에 두 번째 인수로 추가합니다.

extends Node


signal my_signal(value, other_value)


func _ready():
    emit_signal("my_signal", true, 42)

결론

Godot에 내장된 많은 노드 유형은 이벤트를 감지하는 데 사용할 수 있는 Signal을 제공합니다. 예를 들어, 동전을 나타내는 Area2D 는 플레이어의 물리적 몸체가 CollisionShape에 들어갈 때마다 body_entered신호를 방출하여 플레이어가 수집하는 것을 인식하게 할 수 있습니다.

 

반응형

댓글