소닉 프론티어(Sonic Frontier)
작업기간: 2025-04-23 ~ 2025-07-19(약 12주)
기술 스택
- C++
- DirextX11(DX11)
외부 라이브러리
- PhysX
- FMOD Studio
- IMGUI
- ImGizmo
- simd-json
- ImFileDialog
개요
DirectX11을 이용한 모작 프로젝트로, 개인적으로 팬이였던 IP중에 최신 작을 골랐다. 애셋 추출 부터 사용된 기술에 대한 연구까지 동시에 진행했습니다.
프레임워크
Entity-Component-System(ECS) 에 가까운 프레임워크를 작성하여 사용했으며 필요한 시스템들을 싱글턴 으로 선언했고, Engine DLL을 따로 작성하여 세개의 프로젝트로 관리했다. Client, Editor, Engine 이렇게 세개의 프로젝트로 관리했다. 대부분의 기초 컴포넌트와 시스템들을 엔진에서 작성후 동적 라이브러리화 해서 클라이언트에서 접근 가능하게 했으며 모든 시스템을 가지고 있는 싱글턴 인스턴스 하나만 접근 가능하게 했다. DirectX11을 사용하기 때문에 고정 렌더링 파이프라인이 아닌 동적으로 렌더링 했습니다. 멀티 렌더 타겟을 이용해서 지연 렌더링을 했습니다. 충돌과 움직임은 PhysX라이브러리를 사용해서 구현했습니다. 툴용 GUI는 ImGui를 이용해 추가했습니다.
애셋 추출
소닉 프론티어는 자체 엔진 사용으로 Unity와 Unreal Engine처럼 정형화된 추출 툴은 없지만, 모더와 팬들이 제작해둔 툴이 있어 그것을 이용해서 애셋을 추출 할 수 있었다.
모델
추출한 모델과 애니메이션을 FBX로 변환해서 사용했다. 생성시간을 줄이기 위해서 Assimp 라이브러리로 읽고, 필요한 정보만 바이너리 변환을 통해 준비했다. 애니메이션이 있는 모델과 없는 모델의 정보가 다르므로 플래그를 만들어서 변환 과정에서 기록해 다시 읽을 때 문제가 없도록 처리 했다.
메쉬 인스턴싱
추출된 애셋에 정적인 오브젝트의 위치가 담긴 파일이 있어, 이를 블렌더 에서 변환 시킨다음 Python 스크립트를 통해 내 엔진에서 사용할 수 있는 json 형태로 트랜스폼을 저장해 메쉬 인스턴싱으로 렌더링 했다.
애니메이션
뼈를 이용한 애니메이션으로, 정점 쉐이더에서 뼈의 변화에 따른 정점의 위치를 변화 시켜 픽셀 쉐이더로 넘겼다. 현재 애니메이션과 다음 애니메이션의 이어짐이 어색하지 않도록, 애니메이션에 사용된 뼈의 위치를 보간 했다. 상태에 따라서 애니메이션을 바꾸고, 콤보 공격시 특정 시간내에 입력을 계속한다면 다음 공격이 나가게 했다.
게임 오브젝트
게임 오브젝트는 컴포넌트를 들고 있고 이 컴포넌트에 따라 기능이 구현 된다. 게임 오브젝트는 상속관계를 가지고 있으며, 기본적으로 트랜스폼을 들고있다. 자식인 게임 오브젝트는 부모의 트랜스폼에 위치, 크기, 회전, 을 각각 영향을 받을지 말지 결정 할 수 있다.
툴
IMGUI를 통해 뷰포트를 만들었으며, Window 창의 크기에따라서 비율에 맞게 조정될 수 있도록 만들었으며, 그에 따른 UV나 피킹위치에 대해서 보정을 해줬다. 멀티 렌더 타겟을 사용 하고 있기 때문에 원하는 렌더타겟을 뷰포트에 띄워주기 위해 IMGUI에 이미지 복사를 통해 보여줬다. 픽셀 피킹을 통해 선택된 자리에 객체가 있다면 ID를 검색해서 포커스 해주고
UI 툴
텍스쳐 아틀라스를 그대로 사용하기 위해서 텍스쳐의 크기와 선택영역에서 UV를 계산해 쉐이더로 넘겨서 렌더링 했다. 현재 등록된 이미지 파일 중에 선택해서 툴 상에서 파일을 바꾸고 저장할 수 있도록 만들었다.
맵 툴
지형 컴포넌트에서 Height Map 파일을 불러와 실시간으로 평면에 높이를 적용 시켜서 표현할 수 있게 만들었다. 만약 같은 폴더 안에 Splat Map 파일이 있다면 폴더안에 있는 텍스처들을 순회해서 등록해 Splat Map을 통해 지형을 렌더링 했다. 지형 컴포넌트에서 형성된 지형의 정점버퍼와 인덱스 버퍼를 토대로 충돌체 컴포넌트에서 삼각형 메쉬를 만들어서 지형의 과의 충돌을 구현했다. 픽셀 피킹을 통해 위치를 결정하고 IMGUIZMO라는 라이브러를 사용해 기즈모를 사용하거나 숫자를 입력해서 상태를 조정 했다.
스플라인
점과 점사이를 잇는 선분을 캣멀롬 공식에 의하여
아쉬운 점
- 몬스터에 대한 구현을 못했다.
- 상호작용에서 일어나는 버그들
- 레일 모델을 쉐이더를 통해서 스플라인에 따라서 늘려서 표현하려고 했는데 실패했다.
- 중간보스인 아슈라의 충돌로직을 구현하다가 프레임드랍과 오류를 잡지못해 폐기
.gif)