싱글턴 패턴
Coddy GDScript 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 65개 중 46번째.
싱글턴 패턴은 클래스에 객체가 정확히 하나만 있도록 보장하고 모든 스크립트가 그 객체에 접근할 수 있는 하나의 방법을 제공합니다. 게임에 하나만 있는 것, 예를 들어 설정, 저장 시스템, 점수 관리에 사용하세요.
GDScript에서 static var는 단일 객체를 보유하고, static func는 누군가 처음 요청할 때 객체를 생성합니다:
# game_settings.gd
class_name GameSettings
extends RefCounted
static var _instance: GameSettings = null
var volume := 50
static func get_instance() -> GameSettings:
if _instance == null:
_instance = GameSettings.new()
print("Creating settings")
return _instance_instance는 객체가 아니라 클래스에 속하므로 모든 스크립트에서 같은 변수를 봅니다. 첫 번째 호출에서는 변수가 비어 있는 것을 확인하고 객체를 생성하며, 이후의 모든 호출은 같은 객체를 반환합니다.
# main.gd
var a := GameSettings.get_instance()
var b := GameSettings.get_instance()
a.volume = 80
print(b.volume)
print(a == b)Creating settings
80
truea와 b는 하나의 객체를 참조하는 두 변수이므로, a를 통해 변경한 내용이 b에도 반영됩니다. 객체의 경우 양쪽이 동일한 객체일 때만 ==가 true입니다.
GDScript에서는 _init()을 비공개로 만들 수 없으므로, 스크립트가 GameSettings.new()를 호출해 두 번째 객체를 얻는 것을 막을 방법이 없습니다. _instance의 밑줄과 get_instance() 메서드는 서로 간의 약속입니다. 스크립트는 객체를 요청할 뿐, 직접 생성하지 않습니다.
Godot 프로젝트에서 공유 객체 하나를 얻는 일반적인 방법은 오토로드입니다. Project Settings에서 등록하는 스크립트로, Godot가 게임이 시작될 때 한 번 생성하고 모든 스크립트에서 이름으로 사용할 수 있게 해 줍니다. 이는 Godot가 관리해 주는 싱글톤입니다. 오토로드는 에디터에서 설정하므로, 여기의 과제에서는 static var를 사용해 코드로 이 패턴을 구현합니다.
챌린지
쉬움게임의 모든 코인은 하나의 공유 점수에 더해집니다. ScoreManager를 싱글턴으로 만드세요.
- 하나의 객체를
static var에 저장합니다. static func get_instance()는 객체를 반환하며, 첫 호출 시 객체를 생성합니다. 생성 직후Score manager created를 출력합니다.add_points(points)는score에 점수를 더합니다.
coin.gd에서 collect()는 ScoreManager.get_instance()를 통해 코인의 value를 점수에 더합니다.
제공된 코드는 이어지는 이벤트의 개수를 읽은 다음, 한 줄에 하나씩 이벤트를 읽습니다. coin VALUE는 새 코인을 수집하고, bonus POINTS는 점수를 바로 더합니다. 각 이벤트가 끝날 때마다 점수를 출력하고, 마지막에는 get_instance()를 두 번 호출했을 때 같은 객체를 반환하는지 출력합니다. coin 5와 bonus 20을 입력하면 출력은 다음과 같습니다.
Score manager created
Score: 5
Score: 25
Same object: true코드는 score_manager.gd와 coin.gd에 작성하세요. main.gd에는 제공된 입력/출력 코드가 있으며 수정할 수 없습니다.
직접 해보기
extends Node
func _ready():
# 제공된 입출력 코드: 그대로 두세요
var count := int(OS.read_string_from_stdin())
for i in count:
var parts := OS.read_string_from_stdin().split(" ")
if parts[0] == "coin":
Coin.new(int(parts[1])).collect()
elif parts[0] == "bonus":
ScoreManager.get_instance().add_points(int(parts[1]))
print("Score: %d" % ScoreManager.get_instance().score)
print("Same object: %s" % (ScoreManager.get_instance() == ScoreManager.get_instance()))
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 GDScript 컴파일러