프로젝트: CookieRunner (쿠키런 - 오븐브레이크 모작)
Unity를 활용하여 쿠키런 스타일의 2D 러닝 게임을 개발하는 과정에서 사용된 기술과 문제 해결 방법을 정리했습니다. 게임은 플레이어가 지속적으로 오른쪽으로 이동하면서 장애물을 피하고 아이템을 획득하는 방식으로 진행됩니다.
작성자 GitHub: https://github.com/ChinoDaiski
ChinoDaiski - Overview
ChinoDaiski has 28 repositories available. Follow their code on GitHub.
github.com
프로젝트 링크 : https://github.com/YataGarasu8/CookieRuner
GitHub - YataGarasu8/CookieRuner
Contribute to YataGarasu8/CookieRuner development by creating an account on GitHub.
github.com
주요 작업 내용 및 기술적 도전
1. 타일맵 시스템
[ 타일맵을 활용한 맵 제작 ]
Unity의 Tilemap 시스템을 활용하여 맵을 구성하고 관리할 수 있도록 구현했습니다.
.scene 파일 수정으로 인한 병합 문제를 해결하기 위해 JSON/CSV 파일을 활용한 저장 및 불러오기 기능을 추가했습니다.
[ 맵 생성 및 최적화 ]
플레이어가 일정 지점에 도달하면 새로운 타일맵을 생성하고 기존 타일맵을 제거하여 메모리를 절약하는 기능을 구현했습니다.
타일맵 프리팹을 활용하여 게임 진행 중에도 새로운 맵을 자연스럽게 이어 붙일 수 있도록 설계했습니다.
2. 장애물 시스템
[ 장애물 유형별 구현 ]
게임 내 등장하는 장애물을 4가지 유형으로 나누어 구현했습니다.
서 있는 장애물: 특정 위치에서 애니메이션 없이 고정된 형태로 배치됨.
튀어나오는 장애물: 플레이어가 가까이 접근하면 위/아래로 튀어나옴.
사라지는 장애물: 일정 시간이 지나거나 플레이어가 접근하면 사라짐.
날아오는 장애물: 일정 거리에서 생성 후 플레이어를 향해 이동.
[ 장애물 최적화 및 데이터 관리 ]
ScriptableObject를 활용하여 장애물 데이터를 효율적으로 관리하도록 구현했습니다.
ObstacleData에서 프리팹을 직접 포함하지 않도록 개선하여 타일맵 배치 시 성능 최적화를 수행했습니다.
3. 플레이어 시스템
[ 이동 및 충돌 처리 ]
Rigidbody2D를 이용하여 부드러운 플레이어 이동 및 물리 기반 충돌 처리를 구현했습니다.
이동 중 속도가 0으로 초기화되는 문제를 해결하기 위해 CompositeCollider2D를 추가했습니다.
[ 애니메이션 시스템 ]
상태 머신(State Machine) 방식으로 애니메이션을 관리하여 자연스러운 움직임을 구현했습니다.
2단 점프 및 공중에서의 애니메이션 전환을 세밀하게 조정하여, 원활한 상태 전환이 이루어지도록 개선했습니다.
[ 크기 변화 시스템 ]
특정 아이템을 획득하면 일정 시간 동안 플레이어 크기가 증가하고, 이후 원래 크기로 복귀하는 시스템을 추가했습니다.
PlayerStats를 활용하여 크기 변화를 데이터로 관리하도록 설계했습니다.
[ 무적 및 피격 시스템 ]
플레이어가 피격되었을 때 일정 시간 동안 무적 상태가 적용되도록 구현했습니다.
무적 상태가 특정 애니메이션에 종속되지 않도록 별도의 상태 관리 시스템을 적용했습니다.
4. UI 및 씬 관리
[ 로딩 씬 ]
리소스를 로딩하는 동안 별도의 스레드를 활용하여 비동기적으로 작업을 진행하도록 구현했습니다.
메인 스레드는 UI를 담당하고, 로딩 스레드는 리소스 로드 및 데이터 처리를 수행하여 프레임 드랍 없이 부드러운 진행이 가능하도록 최적화했습니다.
진행률을 프로그래스 바 및 텍스트로 시각화하여 플레이어가 현재 로딩 상태를 직관적으로 파악할 수 있도록 구현했습니다.
로딩이 완료되면 일정 시간 후 GameStart 버튼이 활성화되도록 설정하여 자연스러운 씬 전환이 이루어지도록 했습니다.
[ 씬 전환 및 페이드 효과 ]
coroutine으로 fadeImage를 활용하여 화면이 점진적으로 어두워지고 밝아지는 페이드 효과를 적용했습니다.
페이드 효과의 지속 시간을 인스펙터에서 조정할 수 있도록 설정하여 유연성을 높였습니다.
5. 네트워크 및 서버 연동
[ UGS (Unity Gaming Services) 연동 ]
Unity의 Authentication 서비스를 활용하여 플레이어의 로그인 및 토큰 발급 기능을 구현했습니다.
플레이어가 로그인 시 서버에서 인증된 토큰을 반환받고, 이를 게임 내에서 활용할 수 있도록 설정했습니다.
6. 스프라이트 리소스 관리 및 최적화
[ 스프라이트 최적화 ]
Sprite Atlas와 개별 스프라이트의 성능 차이를 분석하여 최적의 리소스 관리 방식을 적용했습니다.
동일한 텍스처를 공유하는 경우 Sprite Atlas를 활용하여 드로우 콜을 최소화하고,
개별 스프라이트 사용이 배칭을 줄이는 데 유리한 경우에는 해당 방식을 선택하여 성능을 최적화했습니다.
[ 애니메이션 최적화 ]
Texture Sheet Animation을 적용하여 애니메이션 스프라이트를 하나의 텍스처로 관리하여 최적화
여러 개의 개별 스프라이트를 사용하는 애니메이션은 Sprite Atlas를 활용하여 배칭을 최적화했습니다.
[ UI 및 2D 렌더링 최적화 ]
UI 요소(버튼, 아이콘 등)는 Canvas의 Batch 처리 방식에 맞춰 UI 전용 Sprite Atlas를 구성하여 최적화
UI가 동적으로 갱신되는 경우 Dynamic Batching이 아닌 Static Batching을 활용하여 성능을 최적화했습니다.
기술 스택
Unity Tilemap 타일맵을 활용한 맵 구성 및 최적화
Rigidbody2D 물리 기반 이동 및 충돌 처리
State Machine 애니메이션 상태 전환 관리
ScriptableObject 장애물 및 데이터 관리 최적화
CompositeCollider2D 충돌 문제 해결
UGS Authentication 플레이어 로그인 및 인증 시스템
GitKraken Git 브랜치 및 프로젝트 관리
프로젝트에서 배운 점
1. UGS 연동 및 비동기 데이터 처리
await / async 방식과 Task를 활용한 비동기 데이터 송수신을 익혔습니다.
리더보드를 통해 실시간 랭킹을 관리하는 기능을 구현하며 서버와의 데이터 연동 방식을 배웠습니다.
2. 스프라이트 리소스 관리 최적화
Sprite Atlas와 개별 스프라이트의 장단점을 비교 분석하고, 상황에 따라 적절한 방식을 선택하는 것이 중요함을 배웠습니다.
3. 싱글턴 패턴을 활용한 매니저 관리
DontDestroyOnLoad를 활용하여 씬 전환 시에도 유지되는 매니저 시스템을 구축하는 방법을 익혔습니다.
4. Rigidbody2D 및 물리 시스템 이해
Unity의 이벤트 함수 주기(FixedUpdate, Update, LateUpdate)의 차이를 이해하고,
FixedUpdate에서 Rigidbody2D 관련 로직을 처리해야 함을 확인했습니다.
5. 타일맵 및 데이터 관리 최적화
ScriptableObject를 활용하여 타일맵 데이터를 효율적으로 관리하는 방식을 익혔습니다.