게임 개발 포트폴리오 | TSEROF
내일배움캠프 1기 Unity 게임 개발 과정 트랙 수료생 최종 프로젝트 'TSEROF '을 소개합니다.
Feb 26, 2024
프로젝트 결과물 소개
- 💭GAMEGUIDLINE
- 시작화면에서 저장 슬롯을 만들고 플레이 해보세요!
- 스테이지선택화면에서 탐험하고 싶은 스테이지를 골라서 스테이지들을 자유롭게 탐험해보세요. (포탈에 불이 꺼져있다면 이전 스테이지를 먼저 클리어해주세요)
- 방향키와 점프를 활용하여 각각의 Stage들을 탐험하고 숨겨진 퍼즐 아이템을 획득해 보세요.
- 📽️INGAME
StartScene
Stage1
StageSelect
Stage2
Stage3
- 📜STORY 어느 날 잠에서 깨어난 소녀 샬롯. 무언가 소중한 걸 잊고 있다는 느낌에 그 무언가를 찾아 여행을 떠나기로 결심하게 됩니다. 샬롯과 함께 여행을 하며 샬롯의 잊어버린 추억의 조각들을 찾아보세요!
기술적인 도전 과제
담당자: 김어진
싱글톤과 interface를 사용하여 코드 개선
⚠️문제 사항
- interface 형태인 C# IDataPersistence는 GameData의 정보를 받아줌.
- 저장과 로드를 담당하는 SaveGame(), LoadGame()
- 저장하고 로드할 변수들을 받아주는 SaveData(), LoadData()
- 저장할 변수들을 설정하는 GameData()
→ 각 함수 간의 기능의 분리가 모호함
→ 저장할 변수가 여러 개의 경우 변수와 관련된 함수들의 구분이 어려움
🆕개선 방식
- C# GameData에 저장할 변수들을 설정
- interface 형태인 C# IDataPersistence는 GameData의 정보를 받아줌.
- SaveData(GameData data), LoadData(GameData data)
- 저장할 변수와 관련된 Script들은 IDataPersistence 상속
- DataPersistenceManager은 싱글톤패턴을 활용하여 구현
💫개선 결과
- 자주 사용하는 함수를 통일함으로써 코드 관리가 용이해짐.
SerializableDictionary와 GenerateGuid()를 사용하여 변수 관리
⚠️문제 사항
- interface 형태인 C# IDataPersistence는 GameData의 정보를 받아줌.
- 저장과 로드를 담당하는 SaveGame(), LoadGame()
- 저장하고 로드할 변수들을 받아주는 SaveData(), LoadData()
- 저장할 변수들을 설정하는 GameData()
→ 각 함수 간의 기능의 분리가 모호함
→ 저장할 변수가 여러 개의 경우 변수와 관련된 함수들의 구분이 어려움
🆕개선 방식
- 배열이 아닌 SerializableDictionary <string, bool> 타입 사용
- Inspector에서 보여주기 위해 SerializableDictionary 사용
- 리스트의 Key값인 string은 GenerateGuid()를 사용해 id를 생성하여 구별
💫개선결과
- Dictonary와 GenerateGuid()를 통해 id를 생성함으로써 코드의 복잡도 감소
XOR 암호화와 백업시스템을 활용한 JSon 기능 보완 및 확장
⚠️문제 사항
→ 유저들이 로컬 파일 내에서 데이터를 변형 및 삭제할 가능성 존재
🆕개선 방식
- 다양한 암호화 방식 중 계산이 가장 빠른 XOR 암호화를 통해 암호화
- File.Copy를 통해 백업 파일을 생성
- C# FileDataHandler에 Main 파일이 만들어지면 백업 파일 자동 생성
- 데이터 로드시 Main 파일과 백업 파일 비교하여 삭제된 데이터 복구
💫개선결과
- 암호화를 통해 데이터의 변형 가능성 낮춤
- 백업시스템을 통해 데이터 삭제시 복원 가능
최적화를 위한 효율적인 Collider 설정
⚠️문제 사항
→ 맵의 모든 개별 오브젝트 하나하나에 Collider를 설정함으로써 충돌 함수에 많은 연산 발생
🆕개선 방식
- 가능한 분류할 수 있는 지형을 기준으로 Collider 전용 오브젝트를 생성하고 광범위한 Collider 설정
- Collider의 밑(지하) 혹은 닿지 않는 부분은 Collider에서 제외
💫개선결과
- 불필요한 연산량을 줄임으로써 최적화
담당자: 김형중
캐릭터의 자유로운 이동과 스테이지 선택 : Waypoint 알고리즘
✨ 아이디어
- 캐릭터가 정해진 경로 위에서 이동해야 함.
- 스테이지 입구에 도달할 때마다 캐릭터가 멈출 수 있어야 함.
→ Waypoint 알고리즘을 사용하여 구현.
⚠️ 문제 사항
- 스테이지 선택씬이 열릴 때마다 캐릭터가 스폰되는 장소가 동일함.
- 스테이지를 완료할 때마다 해당 스테이지 입구 앞에서 스폰되어야함.
→ 게임의 흐름이 자연스럽지 않고 미완성적인 느낌을 줌.
🆕 개선 방식
- Waypoint의 index값을 활용해 스폰되는 포인트를 지정 :
- 스테이지 선택씬에 진입할 때 마다 현재 스테이지에 맞는 Waypoint의 index값을 지정해주어 해당 지점에서 스폰될 수 있도록 조정.
💫 개선 결과
- 캐릭터가 정해진 경로 위에서 자유롭게 이동할 수 있음.
- 스테이지 입구에 도착하면 OnCollisionEnter() 함수를 통해 움직임을 멈추어 스테이지에 도달할수 있음.
- 스테이지가 끝나고 다시 스테이지 선택씬에 진입했을 때, 해당 스테이지의 입구에서 제대로 스폰됨.
담당자: 박지원
상속과 오버라이딩으로 가독성과 효율성 향상
: Top View 고려한 Player 클래스의 개선
⚠️ 문제 사항
- Top view 고려하여 기존의 방식과 다른 플레이어의 이동 방향 조정 필요.
- Player 클래스에 오버로딩이나 조건문으로 문제 해결 시도.
- Top view 여부 지속적 확인 필요.
→ 단일 클래스에서 다양한 view에 따른 기능 추가로 가독성, 효율성 저하 우려.
🆕 개선 방식
- TopViewPlayer 클래스 도입:
- Player 클래스 상속, 메서드 오버라이딩으로 Top view에서만 다르게 동작하도록 조정.
💫 개선 결과
- 코드 구조 명확화.
- 가독성 및 효율성 향상.
모듈화를 통한 가독성 향상
: 이벤트 기반 코드 개선과 효율적인 오브젝트 처리
⚠️ 문제 사항
- 특정 입력 이벤트가 발생할 때마다 직접 코드 호출.
- 상호작용 가능한 오브젝트의 가까움 여부 조건문으로 확인.
→ 코드의 모듈화 및 가독성 저하, 주기적인 조건 확인 필요.
🆕 개선 방식
- 이벤트 함수 도입:
- 입력 부분에 이벤트 함수 적용
- 입력 이벤트 발생 시 콜백 함수 실행으로 코드 모듈화.
- 상호작용 가능한 오브젝트 처리:
- 가까운 오브젝트 상호작용을 조건문이 아닌 충돌 검사로 변경.
- 오브젝트와 충돌 시에만 이벤트 함수에 연결.
💫 개선 결과
- 코드 모듈화 및 가독성 향상.
- 상호작용 가능한 오브젝트의 효율적인 처리.
충돌 최소화를 통한 효율적인 Raycast 활용
: 충돌 Layer 및 RaycastNonAlloc의 적용
⚠️ 문제 사항
RaycastAll
을 사용하여 Laser의 방향에 있는 모든 물체 충돌 확인.
→ 과도한 충돌 발생으로 인한 성능 저하 발생.
🆕 개선 방식
- 충돌 Layer 셋팅:
- 충돌 체크 대상을 Layer로 설정하여 불필요한 오브젝트와의 충돌 체크 효율화.
- RaycastNonAlloc 사용:
RaycastAll
대신RaycastNonAlloc
을 사용하여 내부에서 생성되는 불필요한 메모리 할당 방지.
- 한 번에 하나의 Receiver만 충돌하도록 조정:
- Laser의 각도를 조절하여 한 번에 하나의 Receiver만 충돌하도록 조정.
- 정답 후에는 Raycast 사용 중단:
- 정답을 맞춘 이후에는 Raycast를 더 이상 사용하지 않도록 설정.
💫 개선 결과
- 충돌 최소화 및 성능 향상.
- 불필요한 Raycast 호출로 인한 오버헤드 감소.
RaycastNonAlloc
및 충돌 Layer 설정으로 메모리 할당 최소화 및 효율적인 충돌 체크.
담당자: 정재훈
캐싱과 오브젝트 풀링으로 메모리 최적화
: CPU 부담 감소와 가독성 향상
⚠️ 문제 사항
- 고드름 오브젝트가 떨어지면 즉시 파괴하고 정해진 위치에 다시 생성하는 방식으로 작성.
→ 해당 방식은 스테이지가 끝날 때까지 파괴하고 다시 생성하므로 가비지가 지속적으로 생성되어 CPU 부담이 큼.
🆕 개선 방식
- 캐싱과 오브젝트 풀링을 활용한 효율적인 구현:
- 하나의 오브젝트로 작성하고 오브젝트 풀링과 코루틴을 이용하여 고드름이 바닥에 떨어질 때, 일정 시간이 지난 후 정해진 위치로 돌아오도록 구현.
- 코루틴에서 사용되는
WaitForSeconds
객체를 미리 변수에 담아두고 사용하여 메모리 사용량을 최소화하고 코드의 효율성을 높임.
💫 개선 결과
- 메모리와 성능의 효율을 높임.
- 가비지 생성을 최소화하여 CPU 부담을 감소시킴.
- 코드의 가독성과 유지보수성을 향상시킴.
스크립트 기반 초기화 도입으로 안정성 강화
: 값 빠짐 및 초기화 오류 문제 해결
⚠️ 문제 사항
- 인스펙터 창에서 초기화.
→ 중간에 값이 빠지거나 잘못 넣어지는 문제 발생.
🆕 개선 방식
- 스크립트를 이용한 초기화 도입:
- 자식 오브젝트를 받는 경우, 부모 오브젝트의 코드에서
GetChild()
를 통해 안정적으로 초기화.
💫 개선 결과
- 값 빠짐 및 잘못된 초기화 문제 안정적으로 해결.
코드의 명확성 강조
: 퍼즐 관리를 위한 단일 스크립트와 Static 변수의 도입
⚠️문제 사항
- 각자의 클래스에 변수를 선언하여 퍼즐을 관리.
→ 코드의 가독성 저하 및 관리 어려움.
🆕 개선 방식
- 퍼즐 관리 스크립트 도입:
- 하나의 스크립트에서 퍼즐을 관리.
- Static 변수를 활용하여 다른 클래스에서 쉽게 접근 및 관리.
💫 개선 결과
- 코드의 가독성 향상 및 관리 용이성 향상.
동적 태그 비교의 효율성 향상
: CompareTag() 메서드의 도입
⚠️ 문제 사항
- 콜라이더의 태그를 판단할 때
==
연산자 사용.
→ 정적 문자열 비교로 동적 태그 관리에 한계 존재.
🆕 개선 방식
- CompareTag() 메서드 도입:
CompareTag()
메서드 활용하여 동적 태그 비교.- 동적할당 없이 더 효율적인 태그 비교 구현.
💫 개선 결과
- 코드의 효율성 향상.
- 동적 태그 관리에 용이성 증가.
✔ 개선 발전 가능성
- 다음 프로젝트에서는 태그를 관리하는 변수(const)를 도입하여 가비지 생성을 최소화하고자 함.
담당자: 이홍준
가상 메서드를 통한 코드의 재사용성 향상 및 관리성 개선
⚠️ 문제 사항
- 기믹 스크립트에서 캐릭터와 기믹 오브젝트 둘 다 제어하여 단일성 부족
- 기믹 개수가 늘어날수록 코드의 관리 난이도가 높아짐
🆕 개선 방식
- 캐릭터 제어는 캐릭터 스크립트에서, 기믹 제어는 기믹 총괄 스크립트에서 제어하도록 분리
- 기믹 총괄 스크립트는 가상 메서드로 구성하여 각 기믹 스크립트가 함수를 가져다 쓸 수 있도록 제작
- 기믹 스크립트가 총괄 스크립트를 상속받아 사용하는 방법도 있지만 굳이 상속을 사용하지 않아도 함수를 가져다 쓰는데 지장이 없으며 오버라이딩을 통해 함수를 입맛에 맞게 바꿔쓸 수 있기 때문에 캡슐화에 지장을 줄 수 있는 상속을 사용하지 않음
💫 개선 결과
- 코드의 과도한 중복 제거 (실제로 각 기믹 스크립트의 코드는 약 1500줄 → 400줄로 줄음)
- 코드의 재사용성 및 관리성 향상
사용된 기술 스택
- Visual Studio - 2022
- Rider - 2023.2.1
- Unity - 2022.3.2f1
- GitHub
Design
- Photoshop 2022
- Maya 2020
Collaboration
클라이언트 구조
전체적인 구조
데이터 관리
DataPersistenceManager | 각각의 저장슬롯에 ID를 부여하여 구별시켜줍니다. 그리고 NewGame, SaveGame, LoadGame 함수를 통해 전반적인 데이터 저장을 관리합니다. |
GameData | 게임에 저장할 변수들의 데이터를 담당하고 있습니다. |
IDataPersistence | DataPersistenceManager의 interface로 LoadData, SaveData 함수를 통해 데이터 관리자와 저장할 변수를 연결시켜줍니다. |
FileDataHandler | Json을 활용하여 게임 내 저장한 데이터와 로컬파일을 직렬화&역직렬화를 통해 연결시켜줍니다. |
플레이어 관리
Player | 플레이어의 이동, 회전에 대한 입력을 받고 그에 따른 움직임과 애니메이션을 처리함 |
TopViewPlayer | Player를 상속 받아 top view인 상황에서 플레이어의 이동, 회전에 대한 입력을 처리함 |
ForceReceiver | 플레이어의 점프, 낙하와 관련된 처리, 땅에서와 공중에서의 애니메이션과 움직임을 처리함 |
스테이지 관리
GameManager | 현재 스테이지 값, 클리어한 스테이지 데이터 저장 |
WaypointPath | 캐릭터의 이동과 스테이지 접근 |
MoveSelect | 스테이지 선택씬에서 캐릭터 이동에 따른 현재 접근 스테이지 정보 |
Stage2Manager | Stage2에 진입시 Floor1 실행, 진행 상황에 맞는 Floor 실행, 모든 Floor Clear시 Stage Clear로 판단해 StageSelectScene Load |
기믹관리
PuzzleManager | 퍼즐버튼 랜덤배치 및 퍼즐오브젝트 초기 세팅, 퍼즐 기믹의 성공여부 판단 후 다음 스테이지로 가는 오브젝트 실행 |
LaserPatternManager | 레이저 랜덤 패턴 생성 및 초기 세팅, 모든 Laser 성공 여부 확인 및 패턴 성공시 CutScene 재생 |
Stage3GimmickManager | Stage3 의 모든 기믹에 사용되는 함수를 가상 메서드로 모아서 관리 |
코드 샘플 및 주석
사용자 의견 | 개선방안 | 분류 |
기믹 및 지형에 따라 들리는 소리가 달랐으면 좋겠습니다. | 지형마다 collider를 사용해 AuioClip을 바꾸어주는 방식으로 소리가 다르게 나도록 패치하였습니다. | ALL |
StartScene에서 키보드 클릭이 아닌 마우스 클릭도 있으면 좋겠어요. | EventSystem을 변경하여 키보드 클릭과 마우스클릭 모두 가능하게 변경 | StartScene |
Stage1의 낮은 잎에 닿으면 플레이어가 2단 점프를 하지 못합니다. | Player의 Jump 범위에 문제가 생기지 않게 오브젝트의 위치를 변경하였습니다. 이후에 Jump 메커니즘을 수정할 예정입니다. | Player |
Stage1 나무토막이 바닥에 떨어졌을 때 무조건 캐릭터 리스폰을 해서 나무토막도 리스폰을 시켜야 아이템을 먹을 수 있는 부분이 아쉽습니다. | 캐릭터 리스폰과 관계 없이 나무토막이 떨어진 후 7초가 지나면 원상태로 돌아가도록 수정하였습니다. | Stage1Scene |
게임 플레이 도중 발판 블럭이 리스폰 안 되서 메인으로 나가서 다시 스테이지로 돌아왔는데 시야가 위로 고정되는 버그에 걸렸습니다. | Stage2 Manager의DonDestroyOnLoad함수를 제거 해줌으로써 Start의 카메라 세팅이 매번 작동되도록 수정하였습니다. | Stage2Scene |
스테이지2 용암블럭 앞 얼음블럭이 떨어진 후 젠이 되지 않아 진행할 수 없었습니다. | 몇 개의 얼음 블록은 지속적으로 생성되도록 설정하여 플레이어가 진행하는 데 어려움이 없도록 진행하였습니다. | Stage2Scene |
Stage2-3에서 ESC 버튼이 안 먹습니다. | 2-3 전용 캐릭터에 OptionInput스크립트를 넣어 Option창에 접근할 수 있도록 수정했습니다. | Stage2Scene |
Stage2 고드름 바닥에 떨어졌을때 맞고 죽는 판정을 고쳐주시면 좋겠습니다. | 고드름의 콜라이더를 이용하여 땅에 닿기 전까지는 플레이어가 닿으면 리스폰이 되고, 땅에 닿으면 콜라이더를 비활성화하여 닿아도 아무 효과도 적용되지 않도록 개선하였습니다. | Stage2Scene |
Stage2 원근감 및 거리감이 불편합니다. | Stage2의 전반적인 y축의 높이를 재조정할 예정입니다. | Stage2Scene |
팀원 구성 및 연락처
이름 | 태그 | 역할 | MBTI | 블로그 주소 | Github주소 |
김어진 | 팀장 | GameData,StartScene,Stage1Scene | ENTJ | ||
정재훈 | 부팀장 | Stage2Scene,Gimmick | ENFP | ||
김형중 | 팀원 | StageSelect,Option,Sound | INFP | ||
박지원 | 팀원 | Stage2Scene,Player,Gimmick | ISFP | ||
이홍준 | 팀원 | Stage3Scene,Gimmick | ISTP |
취업 준비, 어디서부터 시작해야 할지 모르겠다면?
🧐비전공자인데 IT 업계 취업할 수 있을까?
😟프로젝트 경험이 부족한데, 어떻게 준비해야 할까?
🥺IT 기업으로 이직하고 싶은데 뭐부터 시작해야 할까?
이런 고민을 하고 있다면, 내일배움캠프의 IT 취업 컨설팅을 받아보세요.
취업 코칭 전문가들이 여러분의 고민을 해결해 드립니다.
다음 링크에 이메일을 입력하시면 메일로 1:1 커리어 상담권과 취준 자료집을 보내드릴게요.
👉상담권 받기
Share article
Subscribe to our newsletter