728x90
본 게시글은 고도엔진 공식문서에 작성된 Using signals를 정리하였습니다.
신호(Signal)
- 버튼을 누르는 것과 같은 특정 상황이 발생했을 때 노드가 보내는 메시지
- 게임 오브젝트가 서로 참조하지 않고도 다른 오브젝트의 변화에 반응할 수 있게 해준다.
- 유니티의 이벤트와 유사한 역할을 한다.
씬 설정
- [GodotDoc][Step by step] 3. 첫 번째 스크립트 만들기(GDScript) 에서 이어서 작업한다.
- 상단 메뉴에서 Scene>New Scene를 선택하여 새로운 씬을 추가한다.
- Scene 도크에서 2D Scene를 선택하여 Node2D 노드가 새로 만든 씬의 루트 노드가 되도록 만든다.
- 이전 작업에서 만들었던
sprite_2d.tscn
씬을 새로 만든 씬의 자식 노드로 배치한다. - [GodotDoc][Step by step] 2. 인스턴스 생성 참고
- Scene 도크에서 루트 노드를 선택한 후, ➕아이콘을 선택하여 새로운 자식 노드를 추가한다.
- Create New Node 팝업창이 열리면 검색창(Search:)에 Button이라고 입력한다.
- Button 노드를 선택한 후 Create 버튼을 선택하여 Button 노드를 추가한다.
- Scene 도크에서 새로 추가된 Button 노드를 선택한다.
- 뷰포트에서 Button 노드의 크기를 조절한다.
- Inspector 도크의 Text 속성 아래있는 텍스트 입력창에 Toggle motion라고 입력한다.
- 작업했던 씬은
node_2d.tscn
으로 저장한다. - FileSytem 도크에서
node_2d.tscn
씬을 우클릭한다. - Scene as Main Scene를 선택하여
node_2d.tscn
씬을 메인 씬으로 설정한다.
에디터에서 시그널 연결
- Scene 도크에서 Button 노드를 선택한 후 Inspector 도크 옆에 있는 Node 도크를 선택한다.
- Node 도크에서
pressed()
시그널을 더블 클릭한다. - Connect a Signal to a Method 팝업창이 열리면서 Sprite2D 노드가 자동으로 선택된다.
- 자동으로 선택되지 않았다면 직접 선택한다.
- Connect 버튼을 선택하면
my_sprite_2d.gd
스크립트에 자동으로_on_button_pressed
함수가 생성된다.
- 앞으로 버튼을 누르면
_on_button_pressed
함수가 자동으로 호출된다. _on_button_pressed
함수에 아래 내용을 추가한다.
func _on_button_pressed():
set_process(not is_processing())
set_process
에 false를 입력하면is_processing
함수는 false를 반환하게 되고, 매 프레임마다_process
를 호출하지 않아 Sprite2D 노드는 움직이지 않는다.set_process
에 true를 입력하면is_processing
함수는 true를 반환하게 되고,매 프레임마다_process
를 호출하여 Sprite2D 노드가 움직인다.- not 키워드를 이용하면
is_processing
의 반대값을 반환하게되어, 버튼을 누를 때마다 Sprite2D 노드의 움직임을 제어할 수 있다.
타이머 추가
- FileSystem 도크에서
spite_2d.tscn
씬을 불러온다. - Scene 도크에서 Sprite2D 노드를 선택한 후 버튼을 추가하였을 때와 동일한 방식으로 Timer 노드를 자식 노드로 추가한다.
- Scene 도크에서 Timer 노드를 선택한다.
- Inspector 도크에서 Autostart 속성 옆의 체크 박스를 체크한다.
sprite_2d.tscn
씬을 저장한다.
코드에서 시그널 연결
- 에디터 대신 코드에서 시그널을 연결할 수도 있다.
my_sprite_2d.gd
스크립트에 아래 내용을 추가한다.
func _ready():
var timer = get_node("Timer")
timer.timeout.connect(_on_timer_timeout)
func _on_timer_timeout():
visible = not visible
_ready
는 노드가 준비 상태가 되었을 때 한번 호출된다.get_node("Timer")
는 자식 노드로 추가했던 Timer 노드를 반환한다.timeout
은 Timer 노드에서 설정한 시간이 되었을 때 동작하는 시그널이다.timer.timeout.connect(_on_timer_timeout)
을 입력하면timeout
시그널이 동작하면_on_timer_timeout
함수를 자동 호출하게 된다.visible
이 true일 경우 노드가 화면에 출력되고, false일 경우 화면에 출력되지 않는다.
커스텀 시그널
- 스크립에서 원하는 시그널을 직접 선언할 수 있다.
my_sprite_2d.gd
스크립트 맨 윗 줄의extends Sprite2D
바로 아래에 시그널을 선언한다.
signal process_enabled
signal visiblity_changed(is_visible: bool)
signal process_enable
처럼 신호만 발생시킬 수도 있고,signal visiblity_changed
처럼 필요한 변수를 함께 전달할 수도 있다.my_sprite_2d.gd
스크립트를 저장한 후 Node 도크를 확인하면 선언한 시그널을 확인할 수 있다.- 선언한 시그널은
emit
함수를 이용하여 신호를 발생시킨다. my_sprite_2d.gd
스크립트에서_on_button_pressed
함수와_on_timer_timeout
함수에 각각emit
함수를 호출하도록 수정한다.
func _on_button_pressed():
set_process(not is_processing())
if is_processing():
process_enabled.emit()
func _on_timer_timeout():
visible = not visible
visiblity_changed.emit(visible)
- 추가한 커스텀 시그널들은 다른 노드에 연결하여 사용할 수 있다.
완성된 스크립트
var speed = 400
var angular_speed = PI
func _init():
print("Hello, world!")
func _ready():
var timer = get_node("Timer")
timer.timeout.connect(_on_timer_timeout)
func _process(delta):
rotation += angular_speed * delta
var velocity = Vector2.UP.rotated(rotation) * speed
position += velocity * delta
func _on_button_pressed():
set_process(not is_processing())
if is_processing():
process_enabled.emit()
func _on_timer_timeout():
visible = not visible
visiblity_changed.emit(visible)
'Godot' 카테고리의 다른 글
[GodotDocs][Your First 2D Game] 1. 프로젝트 설정 (0) | 2024.01.14 |
---|---|
[GodotDocs][Step by step] 5. 시그널 사용(C#) (4) | 2024.01.04 |
[GodotDocs][Step by step] 4. 플레이어 입력 수신(C#) (2) | 2023.12.29 |
[GodotDocs][Step by step] 4. 플레이어 입력 수신(GDScript) (0) | 2023.12.29 |
[GodotDocs][Step by step] 3. 첫 번째 스크립트 만들기(C#) (0) | 2023.12.27 |