Learning
When: 1학년 7월 12일
How:
개인 프로젝트에서 싱글톤 패턴을 사용하다가 왜 굳이 싱글톤 패턴을 씬이 끝날 때 삭제되면 안 되는지에 대한 궁금증이 생겼고, 사실 사용해야 할 것 같을 때 사용하는 거지 구체적으로 싱글톤 패턴의 장점이나 사용 방식에 대해 확신을 가지고 있지 않았기 때문에 싱글톤 패턴에 대해 공부하게 되었습니다.
Understanding:
- 정의 : 싱글톤은 게임 내에 객체를 딱 하나만 만든 다음, 다른 여러 곳에서 그 객체를 참조하는 설계 패턴입니다.
- 장점 :
- 게임 내에서 객체가 단 하나뿐이기 때문에 다른 곳에서 그 객체에 접근할 때 엉뚱한 객체에 접근하여 일어나는 실수를 방지해줍니다. (만약 점수를 관리하는 객체가 2개나 만들어지면 점수를 조작할 때 서로 다른 객체에서 점수를 올리거나 내리는 일이 발생하는 것을 막아줍니다.)
- 싱글톤은 static 키워드로 수식되어 있기 때문에 게임에 한 개만 존재한다는 장점도 있지만, 동시에 참조하기 쉽다는 장점도 있습니다. static 키워드는 클래스에 소속되게 만들기 때문에 굳이 다른 컴포넌트로 접근하지 않고 Class.Instance를 사용하여 접근할 수 있습니다.
- 여러 번 말한 것 같지만 싱글톤은 인스턴스가 하나이기 때문에 그 인스턴스의 값을 누가 어디서 가져오더라도 전부 같은 값을 가져오게 됩니다. 즉 안전성이 많이 올라가는 것이죠
- 단점 :
- 싱글톤은 접근이 쉬운 것이 장점이 될 수도 있지만 다른 코드들이 그 인스턴스 하나에 의존성을 가지게 되는 단점도 생기게 됩니다. 싱글톤은 코드에 문제가 생기거나 고칠 점이 있을 때 그것을 참조하는 것들이 많고, 어디서 참조하는지 찾기도 쉽지 않기 때문에 유지 보수에 어려움을 겪을 수 있습니다.
- 싱글톤은 편하지만 그렇다고 남발한다면 싱글톤이 싱글톤을 사용하고 그 싱글톤을 다른 게임 오브젝트가 사용하는 등 코드가 산으로 갈 수 있기 때문에 편하다고 너무 많은 것들을 싱글톤으로 사용하는 것은 좋지 않습니다.
- 예시 코드
아래의 코드는 제가 개인 프로젝트를 만들 때 왼쪽과 오른쪽 화면의 끝을 구하기 위해 만든 싱글톤인데, 하나씩 설명해 드리겠습니다.- 싱글톤으로 사용할 Instance를 static으로 선언합니다. 여기서 접근을 할 수 있게 만들어야 하기 때문에 프로퍼티로 선언해야 합니다.
- 사용할 변수들을 선언하였습니다. 전 화면의 양쪽 끝 값을 구하는 클래스를 만들었기 때문에 이렇게 LeftEnd, RightEnd 변수가 있습니다. 물론 필요한 값이 변수에 있기 때문에 변수도 프로퍼티로 만들어야 합니다. static으로 수식되어 클래스의 소속이며 하나 밖에 없는 Instance로 접근하면 하나의 오브젝트로만 통하기 때문에 때문에 변수는 static으로 선언할 필요 없습니다.
- Awake() 메서드에서 Instance에 값을 참조시킵니다. 여기서 중요한 것이 있는데, 싱글톤은 처음 생성하고 더 이상 새로 만들지 않는 경우가 많습니. 그렇기에 DontDestroyOnLoad() 메서드를 사용하여 처음에 생성된 인스턴스를 지키는데, DontDestroyOnLoad()를 한다고 해서 게임 오브젝트가 새로 생성되는 것을 막을 수는 없기 때문에 새로운 싱글톤 컴포넌트를 가지고 있는 오브젝트가 또 생성됩니다. 여기서 Instance에 값이 들어있으면 처음에 값이 참조된 Instance가 아직 파괴되지 않았다는 뜻이기 때문에 (static이라 이전에 생성된 Instance가 계속 유지되므로 새로 생성된 오브젝트의 Instance도 원래 Instance가 참조하고 있던 값이 남습니다.) 이것을 해결하기 위해선 아래에 보이는 조건문을 사용해 Instance가 참조하는 것이 있는지 보고, 있으면 지금 게임 오브젝트를 삭제, 없으면 처음에 해야 할 일들을 시키는 방식으로 사용할 수 있습니다.
using Unity.VisualScripting;
using UnityEngine;
public class EndManager : MonoBehaviour
{
public static EndManager Instance { get; private set; }
public float LeftEnd { get; private set; }
public float RightEnd { get; private set; }
private void Awake()
{
if (Instance == null)
{
Instance = this;
GetEnd();
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
private void GetEnd()
{
LeftEnd = Camera.main.ViewportToWorldPoint(new Vector2(0, 0)).x;
RightEnd = Camera.main.ViewportToWorldPoint(new Vector2(1, 1)).x;
}
}
Result: 싱글톤은 접근도 쉽고 하나이기 때문에 안전하여 편리하게 사용할 수 있지만, 편리하다 보니 너무 많이 사용한다면 나중에 코드를 고치기 매우 어려워지니 주의하여 사용하시는 것을 추천드립니다.
'UnityEngine' 카테고리의 다른 글
| [Unity] ~캐스트(~cast) (0) | 2025.07.21 |
|---|---|
| [Unity] SceneManager (0) | 2025.07.21 |
| [Unity] Overlap~ (2) | 2025.07.10 |
| [Unity] 룰 타일 (Rule Tile) (1) | 2025.07.07 |
| [Unity] 코드로 타일 깔기 (0) | 2025.07.06 |