개요
짧막 소개
상용 게임에 필요한 주요 시스템의 구현 및 설계 노하우를 공유하는 강의를 기반으로 진행하는 스터디이다
이 스터디에 참여하는 이유는, 최근에 진행하고있는 프로젝트에 적용할 수 있는 지식을 습득하는 것이며 나아가 아키텍트를 목표로 하는 나로서는 업계 경력자인 지식 공유자의 설계를 보고 인사이트를 얻을 수 있는 기회라 생각했기 때문이다
학습을 진행할 때 사용한 프로그램은 다음과 같다
- Unity 2022.3.39f1 Apple Silicon
- JetBrain Rider 2023.1.1.
- Github Desktop
학습 방향
생각해둔 학습의 지향점 및 순서는 다음과 같다
- 강의 학습
- 내용 정리
- 실전에서 사용할 땐 어떤식으로 바꾸어야 할까, 고민해보기(개선점 등)
내용
1. 오리엔테이션
개발 환경 세팅 진행
학습을 진행할 프로젝트를 셋업하는 과정이다
이 과정에서 처음 본 세팅이 있었는데, Asset Serialization이 그 주인공이다.
Project Settings => Editor에서 찾을 수 있는 이 속성은, 에셋의 직렬화를 Text/Binary/Mixed 중 어떤 식으로 저장할지 선택하는 항목이다
실제로 설정을 바꾸었을 때, 메타파일 등 에디터 파일들의 내용이 Binary 데이터 혹은 Text 데이터로 변환 되는 것을 확인할 수 있었다
각 모드를 선택했을 때의 가장 큰 차이점은 성능으로 보이는데, 갈 수록 컴퓨터 성능이 좋아지고 있어 굳이 바이너리 모드를 선택해야 하나 싶다
게다가 그럴일은 거의 없겠지만, 혹시나 메타 파일에 문제가 생겼을 때 바이너리 파일을 보고 문제를 찾기 힘들 것 같다
평소에 실무에서도 충돌이 일어나면 메타파일을 텍스트 에디터로 열어 수동으로 충돌을 해결할 때가 있는데, 바이너리로 설정하면 이런 경우에 대처할 수가 없을 것 같다
따라서 특별한 이유가 없다면 Text 세팅을 고수할 것 같다
2. 주요 씬(Scene) 설계
주요 씬 설계 진행
지식 공유자는, 이번 강의에서 사용될 프로그램을 Title - Lobby - InGame의 세 씬을 이용하여 구현하였고 그 이유는 다음과 같다
- 씬 설계의 핵심은 개발 및 유지 보수 과정이 편리해지고 생산성을 높일 수 있어야 한다
- 1의 원칙을 가져왔을 때, 유니티로 만드는 캐주얼 게임 및 미드코어 수준의 게임이라면 3개의 씬으로 게임을 구성하는게 효율적이라는 생각이다
위 원칙을 바탕으로, 이 강의에서 설명하는 각 씬들의 역할은 다음과 같다
Title
- 로고, 로딩 연출
- 자연스러운 주요 데이터 셋업
- 전역으로 사용되는 오브젝트 관리에 사용
Lobby
- 아웃게임 컨텐츠 구현
InGame
- 게임의 핵심 컨텐츠 구현
- 다른 성격의 게임 플레이 씬마다 구현
- 비슷한 시스템이 반복된다면 씬을 분리하지 말 것
그리고 각 씬의 역할을 학습하며 실무에서 어떻게 적용할지 고민하는 시간을 가졌다
우선 강의에선 Title 씬에서 주요 데이터 및 시스템 오브젝트를 싱글턴으로 배치하는 것 같았는데, 프로젝트 규모가 커지면 DB 씬이라던지, Manager만 관리하는 씬이라던지, 역할에 맞게 씬을 더 분리하면 좋을 것 같다는 생각이 들었다
실제로 씬도, 싱글턴 오브젝트도 뒤죽박죽 섞여있는 프로젝트에 잠깐 참여했는데 코드를 학습하는 데 쓸데없이 너무 시간이 들었던 경험이 있다
로비씬의 경우, 실무에서의 주요 쟁점은 '어떻게 연출할 것인가'여서 씬 자체의 개선 방안에 대해서는 크게 생각할 부분은 찾지 못하였다
UI 관련 시스템을 어떻게 효율적으로 구현할까 정도로 보인다
인게임 씬의 경우 컨텐츠가 추가된다고 가정했을 때 씬을 새로 만드는 기준을 무엇으로 잡을지 고민이 되었다
여태 플레이 했던 게임들을 생각해봤을 때, 적절한 분리의 예시로 생각나는 것이 페르소나 시리즈의 미궁 탐험 씬과 전투 씬 분리였다
그럼 여기서 또 어떻게 최적화를 진행할지 자연스러운 연출을 보여줄 지 꼬리에 꼬리를 물고 고민을 했는데 때마침 스터디원이 좋은 질문을 해주었는데
덕분에 개발자가 해결해야 할 문제가 무엇인지, 여지껏 문제는 어떻게 해결했는지와 그에 따른 예시 등. 구체적으로 떠올리고 리마인드 해보는 시간을 가질 수 있었다
SingletonBehaviour
이름에서 역할을 직관적으로 보여주는 클래스였다 (Singleton pattern - Wikipedia)
싱글톤은 굉장히 양날의 검이라고 생각되는 디자인 패턴이다. 하지만 적절히 사용한다면 이보다 더 편리할 수가 없는 클래스라 생각된다
구현은 평범한 싱글톤으로 구현되었고, 특이사항으로는 Awake에서 무조건 Init을 호출하고, OnDestroy에서 Dispose를 호출하게 구현하였다
protected void Awake()
{
Init();
}
protected virtual void Init()
{
if(ins == null)
{
ins = (T)this;
if(!isDestroyOnLoad)
{
DontDestroyOnLoad(this);
}
}
else
{
Destroy(gameObject);
}
}
protected void OnDestroy()
{
Dispose();
}
protected virtual void Dispose()
{
ins = null;
}
이 강의에서 구현된 코드를 보며 느낀점은, 사용자의 실수를 막기 위해 Awake와 OnDestroy를 직접적으로 사용하지 않고, 적절한 네이밍의 메서드를 재정의하여 사용하게 만들었다고 봤다. 그리고 이런 실수 방지 코드 하나하나가 실무에서의 디테일이 아닐까 싶다
또한, 강의에선 전역적으로 사용되는 객체를 바로 싱글톤으로 만들어버리던데, 모두 싱글톤으로 만드는 것이 맞을까 라는 생각도 있다
아마 싱글톤처럼 사용해야 하는 클래스가 꽤나 있을 텐데 이를
- 큰 역할에 따라 싱글톤 루트 오브젝트를 만들기
- 오브젝트가 모든 참조를 지니게 해서 전역적인 참조를 지니게 하기
- 초기화 단계에서 캐싱하여 사용
이랬을 때 좀 더 관리가 편했던 경험이 있다
Logger
강의에선, 단순히 유니티가 제공하는 Debug.Log를 래핑하는 static 클래스를 만들어서 최적화를 진행하였다
내부적으로 전처리기를 사용하여 빌드할 때 해당 플래그를 빼면 최적화가 이루어지는 구조였는데, 래핑하는 아이디어가 굉장히 돋보였다
이에 추가적으로 개선사항을 적어보자면, 각 로그를 출력할지 하지 않을지 결정하는 기능이 추가되었으면 좋을 것 같다
실무에서 디버그를 진행할 때 굳이 코드를 지웠다가 다시 써야하는 상황이 생기는 경우가 있었는데, 자주 로깅이 필요한 클래스는 에디터에서 로깅을 On/Off를 설정할 수 있는 기능을 사용했을 때 굉장히 편리했던 경험이 있다
3. Title 시스템 제작
SceneLoader
Unity가 제공하는 AsyncOperation을 이용하여 비동기적 로딩을 쉽게 연출할 수 있다
모듈 자체는 큰 내용이 없지만, 싱글 게임이 아니고 로딩 사이 실시간 네트워크 데이터를 받아와야 하는 경우에는 어떻게 구현될 까 상상해보았는데
나라면 전체 로딩을 관장하는 LoadingHandler를 구현하고, SceneLoader의 Load 결과를 알려주는 메서드 구현하여 로딩바를 업데이트하는 방향으로 구현할 것 같다
Camera
URP 사용시 적극적인 Camera Stack을 사용하는 것이 포인트인데, 이를 사용하면 생기는 장점은 다음과 같다고 생각한다
- 포스트 프로세싱 등 필요한 효과를, 필요한 카메라에만 적용 가능
- 특정 레이어의 Culling제어가 쉬워짐
- UI 외에도 미니맵 연출, 편리한 시점 변환 등. 구현만 해놓고 enable 여부로 편리하게 사용 가능
복잡해진다고 생각이 들면 적극적으로 사용해야 한다고 생각한다
마무리
프로젝트 마감과 함께 여러 일이 겹쳐 너무 힘든 주간에 진행된 학습이었지만 괜찮은 인사이트를 건질 수 있던 학습이었다
어떻게 하면 스터디를 효율적으로, 내게 이득이 되는 방향으로, 200% 활용할 수 있을지 계속해서 고민해봐야겠다
- 실시간으로 올라오는 다른사람들의 정리 및 인사이트 정독하기
- 같은 자료를 읽고 서로 다르게 정리한 블로그 글 정독
- 강의를 시청하며 실무에서 어떻게 적용할지 고민해보기
- 추가로 학습하면 좋을 자료 찾아보기
2주차는, 위의 요소들을 좀 더 신경써서 많은 아웃풋을 낼 수 있게 노력해봐야겠다
'Unity' 카테고리의 다른 글
유니티 시스템 프로그래밍 Pt.1 - 7~8 주차 (3) | 2024.11.08 |
---|---|
Unity UniTask와 Coroutine (4) | 2024.10.04 |
유니티 시스템 프로그래밍 Pt.1 - 4주차 (0) | 2024.09.29 |
유니티 시스템 프로그래밍 Pt.1 - 3주차 (2) | 2024.09.16 |
유니티 시스템 프로그래밍 Pt.1 - 2주차 (0) | 2024.09.16 |