꾸준실습 복습요약
싱글톤 구현
싱글톤이란 특정 클래스의 인스턴스 가 게임 내에서 하나만 존재하도록 하는 패턴이고, 어디에서나 접근 가능한 객체를 생성해 편하게 사용하기 위해 쓴다고 한다. 게임의 전체적인 룰 등의 시스템을 관리하는 클래스를 만들어 사용할때 쓰게될것이다.
싱글톤은 정적(static)필드를 활용하여 구현한다고 한다. 근데 정적(static)이 어떤 뜻인지 제대로 설명을 들은적이 없다.. gpt찬스!
[GPT와의 문답]
{
Q. C#에서 정적 필드(static)는 어떤 뜻이야? 정적인 필드와 정적이지 않은 필드의 차이점은 뭐야? 그리고 싱글톤에서 정적(static) 필드를 활용하여 구현하는 이유가 뭐야?
A.
C#에서 정적 필드(static field)는 클래스의 인스턴스가 아닌 클래스 자체에 속하는 변수를 의미합니다. 이는 클래스의 모든 인스턴스가 동일한 정적 필드를 공유한다는 뜻입니다.
정적 필드와 비정적(인스턴스) 필드의 차이점
- 정적 필드(static field):
- 클래스 수준에서 존재하며, 프로그램 실행 시 한 번만 메모리에 로드됩니다.
- 모든 인스턴스가 동일한 값을 공유합니다. 한 인스턴스에서 값을 변경하면 다른 모든 인스턴스에 영향을 미칩니다.
- 인스턴스 생성 없이도 접근할 수 있습니다. (ClassName.StaticField 형식으로 접근)
- 비정적 필드(instance field):
- 인스턴스 수준에서 존재하며, 각 인스턴스마다 별도의 복사본을 가집니다.
- 인스턴스마다 고유한 값을 가지며, 한 인스턴스의 값 변경은 다른 인스턴스에 영향을 주지 않습니다.
- 인스턴스를 통해서만 접근할 수 있습니다. (instanceName.FieldName 형식으로 접근)
싱글톤에서 정적 필드를 활용하여 구현하는 이유
싱글톤 패턴은 특정 클래스의 인스턴스를 하나만 생성하고, 어디서든 그 인스턴스에 접근할 수 있도록 보장하는 디자인 패턴입니다.
- 유일한 인스턴스 저장: 정적 필드를 사용하여 클래스 내부에 단 하나의 인스턴스를 저장합니다. 이렇게 하면 프로그램 전체에서 이 인스턴스를 공유할 수 있습니다.
- 글로벌 접근점 제공: 정적 메서드나 속성을 통해 언제든지 동일한 인스턴스에 접근할 수 있습니다.
- 인스턴스 생성의 통제: 생성자를 private이나 protected로 선언하여 외부에서 인스턴스 생성을 막고, 클래스 내부에서만 인스턴스를 생성하도록 합니다.
}
정리하자면 정적(static)이란 클래스 자체에 속하는 하나의 불변한(?) 값이고, 어디에서나 동일한 값에 접근하는걸 허용하기 위해 정적 필드를 쓰는것이다.
싱글톤 구현에는 프로퍼티 를 사용하게 되는데, 정적 프로퍼티 Instance에서 정적 필드인 instance에 get을 사용해 값을 읽어올수 있도록 해야하며, 동시에 게임에서 꼭 인스턴스가 존재하도록 체크할수도 있기 때문이다.
이렇게 구현해주면 전체 게임에서 언제나 접근할수 있는 하나의 클래스가 완성된다.
오브젝트풀 구현
오브젝트풀은 앞으로 끊임없이 마주치게 될것같다. 지금 수준에서 최적화 관련 패턴의 꽃이라고 생각된다.
오브젝트 풀링이란 게임 내에서 많은 수가 존재하게 될 오브젝트가 생성(Instantiate)및 파괴(Destroy)를 반복하게 되면, 시스템 내에 정크(가비지 콜랙션)가 많이 쌓이게 되어서 성능에 영향을 끼칠수 있기때문에, 오브젝트들을 미리 많이 생성시켜놓고, 활성화와 비활성화를 통해 게임이 동작되도록 하는 패턴이다.
ObjectPool 클래스
게임 오브젝트 프리팹을 선언하고 List<GameObject>에 오브젝트를 저장 관리해주는 것이다... 그래서 List가 뭔데? gpt찬스~
[GPT와의 문답]
{
Q. 그래서 List가 뭔데?
A. List<T> 는 동일한 타입의 객체를 순서대로 저장하는 동적 배열입니다.
특징
- 인덱스 기반 접근: 요소를 인덱스를 통해 빠르게 접근할 수 있습니다.
- 순서 유지: 요소들이 추가된 순서를 유지합니다.
- 중복 허용: 동일한 값을 가진 요소들을 여러 개 포함할 수 있습니다.
언제 사용하나요?
- 순서가 중요한 데이터 집합을 다룰 때.
- 인덱스를 통해 요소를 접근하거나 순회해야 할 때.
}
List엔 내부에 있는 값을 찾아올때 내부에 있는 오브젝트를 하나씩 다 확인해보기 때문에 같은 오브젝트만 들어가는 이런 경우에 쓰게 되는것 같다.
그외 Start에서 for문으로 poolSize만큼 오브젝트를 생성해주는것쯤은 서술을 안해도 기억을 잘 할것이다.(라면서 서술해버린다.)
풀 안에 값을 채울수 있으니 이제 값을 빼오고( Get() 메서드 ), 다 쓰고 파괴하는 대신에 다시 풀로 반납해주도록(Release) 하면 된다.
get()을 호출하면 풀속에 오브젝트들을 훑어보게 되고(foreach(GameObject go in pool)),
그중에서 쉬고있는것이 있다면(if(!go.activeInHierarchy)) 그것을 활성화시켜(go.SetActive(true)) 할당해준다(return go).
이렇게 완성된 ObjectPool 클래스로 한 오브젝트당 한 풀을 만들어줬고, 이제 그 리스트들을 키값(key)으로 관리하기 위해 Dictionary를 사용해 관리해줄 것이다. 즉 ObjectPool들을 관리할 상위 클래스가 필요하다.
ObjectPoolManager 클래스
Dictionary는 List와 같은 제너릭 컬렉션이지만, 어떤 차이가 있는건지 알아보자.
[GPT와의 문답]
{
Q. Dictionary는 뭐고, List와의 차이점은 뭐야?
A. Dictionary<TKey, TValue>는 키-값 쌍을 저장하는 컬렉션입니다.
특징
- 키 기반 접근: 키를 통해 값에 빠르게 접근할 수 있습니다.
- 키의 고유성: 각 키는 고유해야 하며, 중복된 키를 허용하지 않습니다.
- 순서 미보장: 요소의 저장 순서는 보장되지 않습니다.
언제 사용하나요?
- 고유한 키를 사용하여 데이터를 빠르게 검색해야 할 때.
- 키-값 쌍으로 데이터를 관리해야 할 때.
차이점 요약
특성 List Dictionary
데이터 접근 | 인덱스 (list[0]) | 키 (dictionary["key"]) |
순서 보장 | 요소의 추가 순서 유지 | 순서가 보장되지 않음 |
키의 고유성 | 해당 없음 | 키는 고유해야 함 |
중복된 값 허용 | 예 | 값은 중복 가능하지만 키는 중복 불가 |
검색 속도 | 요소 수에 비례 (O(n)) | 키를 통한 빠른 검색 (O(1)) |
}
결정적인 차이점은 데이터 저장-접근 방식인것같다. List는 인덱스로 데이터에 접근해 대충 제일 빠른순서에 있는걸 가져오기 좋고, Dictionary는 키값으로 특정한 데이터를 콕 집어 가져오기가 편한듯 하다. List로 그걸 하려면 이름을 가지고 모든 인덱스를 순서대로 검사해야 하니..
이렇게 Dictionary를 사용한 풀링이므로 List를 사용한 오브젝트풀과 달리 함수에서 key값을 요구한다.
// 고민해볼것
둘다 Get과 Release를 같은 이름 다른 조건으로 사용하는데 그냥 한클래스에서 오버로딩을 시도해봐도 될것같다.
'게임개발 > Unity' 카테고리의 다른 글
24-10-28 Unity 숙련 개인과제 04 (0) | 2024.10.28 |
---|---|
24-10-25 Unity 숙련 개인과제 03 (1) | 2024.10.25 |
24-10-23 Unity 숙련 개인과제 01 (0) | 2024.10.23 |
24-10-17 Unity 2D 팀 프로젝트 03 (0) | 2024.10.17 |
24-10-16 Unity 2D 팀 프로젝트 02 (1) | 2024.10.16 |