동영상주소 : https://youtu.be/RV5I0MysqTI

원신 모작 - 개인프로젝트

[구현]

캐릭터

종려(바위) - 공격, 원소공격, 궁극기, 점프, 활강, 대시

클레(불) - 공격, 원소공격, 궁극기, 점프, 활강

라이덴(번개) - 공격, 원소공격, 궁극기, 점프, 활강

나히다(풀) - 공격, 원소공격, 궁극기, 점프, 활강

아야토(물) - 원소공격, 순간이동, 궁극기, 점프, 활강, 대시

 

캐릭터 상태 제어 - 상태 패턴을 이용하여 관리

캐릭터 애니메이션 보간 - 0.2초내 수행된 애니메이션 을 선형보간 (최대 4개)

 

속성데미지 - 해당 오브젝트와 동일 속성인 경우 데미지 수치 조절

원소데미지 - 원소가 부착된 상태에서 원소공격을 할 경우 해당 원소 반응에 따른 데미지 조절

 

대사 - 큐에 넣어서 소리가 겹치지 않고 순차적으로 나오게 설정

 

[오브젝트 관리]

오브젝트 풀링

몬스터의 경우 재사용 될 수 있도록 사망시에 죽음으로 처리하여 안보이게 하고

필요시에 죽음으로 처리된 오브젝트를 확인하여 초기화시켜줌

 

인스턴싱

1000개의 원점으로된 점을 갖는 버퍼를 생성하여 사용

현재 활성화 된 이펙트의 개수만큼 셰이더에 값을 미리 전달

2D의 텍스쳐의 경우 점을 버텍스 셰이더에 전달

지오메트리셰이더를 통해 활성화된 이펙트의 경우 정점을 생성해 픽셀셰이더로 전달

 

[충돌처리]

SAP를 이용하여 충돌처리 최적화

정적 오브젝트와 동적오브젝트 분리

정적 오브젝트의 경우 처음에 한번정렬하고 추가 혹은 삭제될경우 갱신시켜 정렬 비용을 낮춤


[데칼]

SSD를 이용하여 터레인에 텍스쳐를 붙임

큐브박스를 이용하여 붙일경우 큐브안에 들어갔을 때 잘안붙는 현상

벽이 부드럽지않고 가파를때 잘붙지 않는 현상

노말맵을 정확하게 사용하지 못하여서 어색한 부분 보임


[몬스터]

슬라임 - 이동, 공격

란란루 - 이동, 공격, 순간이동(일정 거리 벗어날 경우)
보스(야타) - 할퀴기(특정거리 이내), 내려찍기(특정거리 이상)

 

[셰이더]

그림자

해상도의 가로, 세로 5배 크기의 렌더타겟을 이용해 오브젝트를 특정위치에서의 깊이값 기록

현재 카메라와의 깊이값 비교를 통해 그림자 생성하고 블러처리를 통해 자연스럽게 함


디졸브

노이즈 텍스쳐의 rgba 값을 이용하여 구현


왜곡

중간값으로 초기화된 렌더타겟에 왜곡이 일어난 부분을 기록하여 최종렌더타겟을 왜곡


톤맵핑

빛을 강하게 받을 경우 흰색의 되는 현상을 제거하기 위해 ACES 공식을 대입

 

[기믹]

블럭퍼즐
블럭 선택시 해당블럭과 연결 된 같은 블럭 제거
무지개블럭 - 블럭제거시 연결되어 제거 가능
상하좌우블럭 - 해당블럭의 줄과 열에 해당하는 블럭 제거
점수가 오를 수록 내려오는 블럭의 종류 증가를 통해 난이도 조절

전구퍼즐
전구 클릭시 해당전구와 인접한 전구의 스위치가 반전됨
모든 전구에 불이 들어올 경우 해당스테이지 클리어

 

[기타]

피킹

해당 오브젝트의 원형의 가상 구체를 이용해 피킹 판별

 

스테이터스, 아이템창

캐릭터와의 값 연동

UI창 활성화시 게임 일시정지

 

[아쉬운 점]

- 애니메이션 제어를 완벽하게 하지 못하였다.

- 애니메이션의 루트 이동값을 빼고 코드로 제어하였는데 각 장단점이 존재하였다.

- 이펙트의 경우 인스턴싱 처리를 하였지만 메시의 경우 인스턴싱 처리를 하지 못했다.

- 오브젝트의 바이너리를 통해 불러왔음에도 메모리를 평균 3GB 정도 사용하여 LOD를 시도하지 못하였다.

- 그림자의 경우 해상도가 큰 렌더타겟 사용시 메모리를 생각보다 많이 잡아먹어 고해상도를 사용하지 못하였다.

- 기회가 되면 그림자는 캐스케이드 셰도우 기법을 사용해보고 싶다.

[느낀점]

- 해당 게임의 경우 최적화가 상당히 잘 된 게임이란 걸 알 수 있었다.

- 캐릭터의 이동의 경우 캐릭터별로 애니메이션 정보를 다 불러오도록하였는데

- 실제 게임에서는 캐릭터의 파트(망토)의 움직임과 각 체형(남, 여, 어린아이)의 움직임을 합쳐서 사용하는 것 같다.

- LOD 적용이 아주 잘 되어있다. 거리가 가까울 때 바로 보이지 않고 거리+응시할경우 해당 객체의 선명도가 올라간다

- 타 게임에 비해 디테일이 잘 잡혀있어 새로운 컨텐츠 개발이 생각보다 쉬운 구조로 되어있다.

동영상주소 : https://youtu.be/QE1puDnkN-g

라그나로크 모작 - 팀프로젝트(4인)

 

[구현]

-

 

[아쉬운 점]

-

 

[느낀점]

-

 

 

 

동영상 링크 : https://youtu.be/qPkgAsugrzk

 

[구현]

 

오브젝트

플레이어 : 기본적인 이동과 엎드리기 밑 아래점프 구현

몬스터 : Monster 부모 클래스를 상속받아 몬스터 별 세부적인 설정을 할 수 있도록 함

NPC : Button 클래스를 이용하여 Click시에 해당 NPC의 이벤트 발생

펫 : 플레이어를 따라다니도록 하며 주변의 아이템과 충돌검사로 아이템 습득

이동 : 사각형과 직선의 충돌검사를 통한 선타기 적용

포탈 : 충돌검사 후 윗방향키를 누를경우 씬전환

히든포탈 : 근처에 갈경우 활성화 되며 포탈과 동일한 로직 적용

 

스킬

스트라이크애로우 : AABB충돌을 통해 범위 판정

페이탈블리츠 : 스킬에 DeltaTime 인자를 주어서 일정주기로 공격

제네시스 : 큰 범위 공격을 하며 주변 지형을 파악해 추가적인 이펙트를 소환

벽력일섬 :  TimeManager를 통해 게임의 시간을 느리게 흘러가도록 구현

콤보데스폴트 : CameraManager를 통해 게임화면을 움직이게 하는 효과를 구현

 

이펙트

오브젝트 풀링을 이용하여 데미지 이펙트와 같이 재사용성이

높은 오브젝트를 재생성하지 않도록 구현

 

퀵슬롯

플레이어가 퀵슬롯의 수 크기의 int배열을 갖고 있고 특정한 값을 부여하여

특정 키를 눌렀을 때 해당키에 맞는 값을 이용해 아이템, 스킬 사용

 

인벤토리

struct를 이용하여 장비, 소비, 기타 를 각각 나누고 배열 형태로 Player클래스가 소유 하도록 함

장착/해제 (클릭 & 클릭) : MouseManager를 통해 클릭할 경우 해당장비 위치 값을 전달

장착/해제 (더블클릭) : MouseManager를 통해 더블클릭을 판별하고 해당장비 위치 값 전달

이동 : 기본적인 Swap을 통해 해당 위치를 교환

버리기 : 장비가 선택된 상태에서 UI를 제외한 화면을 클릭할 경우 버려지도록 구현

 

아이템

툴팁 : 상단, 중단부, 하단부를 나눠서 합치는 방식으로 구현

스타포스 : 장비를 스타포스레벨에 따른 확률로 강화 할 수 있도록 구현

 

스테이터스

스탯 : 실시간으로 스탯을 찍을 시 적용되도록 구현

자동배분 : 현재남아 있는 스탯을 모두 자기 직업에 맞는 스탯으로 전환

 

옵션

배경음, 효과음 : SoundManager를 통해 전반적인 값 통제

스킨, 스킨효과 : 현재 플레이하는 Player에게 데미지스킨과 효과를 설정할 수 있도록 인자 값 전달

 

사망

사망시에 사망 UI가 나오게 되며 확인버튼을 클릭시

나오가 나타나게 되며 일정시간 뒤에 플레이어를 회복시켜줌(스킬로 구현)

 

인터페이스

포커싱 : MouseManager를 통해 현재 최상단에 위치한 UI를 파악하여 클릭시에 가장 앞으로 올수 있도록 구현

드래그 : UI의 윗부분에 보이지 않는 네모박스를 통해 드래그 할 수 있도록 구현

 

퀘스트

플레이어가 list의 형태로 퀘스트 클래스를 소유하고 있으며

특정 행동시 플레이어가 list를 순회하며 값을 변동 시키도록 함

 

상점

구매 목록 : NPC는 list를 통해 특정 값을 갖고 있으며 ItemManager를 통해 해당 아이템 나열

판매 목록 : Player의 Itemlist를 순회하여 아이템 나열

스크롤 : 드래그 상태를 체크하고 현재 마우스위치에 맞는 위치로 이동후 아이템 나열

 

보스

낙하물 : 일정 주기로 소환

찌르기 : 플레이어가 근처에 있을경우 시전

돌진 : 플레이어와 멀어질 경우 돌진을 시전

검기발사 : 랜덤한 확률로 검기 발사를 시전

HP게이지 : 선형보간을 통해 이전 HP와 현재 HP를 비교하여 나타냄

 

카메라

기본적인 Culling을 통해 해당 카메라 범위 밖에 있는 오브젝트는 출력하지 못하도록 함

Alpha 값이 필요한 오브젝트의 경우 Alpha 값이 존재할 경우 GdiPlus를 사용하고 

그렇지 않을 경우에는 Gdi를 이용하여 출력하도록 함

 

 

[아쉬운 점]

GdiPlus의 경우 연산이 무거워 자유롭게 사용 할 수 없었다.

Plgblt를 통해 회전을 사용하고 OBB를 이용하여 충돌처리를 해보고 싶었는데 하지 못하였다.

현재는 충돌보다는 Render의 부담이 더 크기 때문에 충돌에 부담을 느끼지 못하여

O(n^2)의 일반적인 방법을 사용하였는데 추후에 SAP 혹은 BSP를 이용하여 충돌처리를 해보고 싶다.

싱글 플레이라는 가정하에 싱글톤을 남발하여 구현을 한 경향이 있는데

만약 서버의 입장에서는 데이터를 어떻게 처리해야 할지 정답을 찾지 못해 아쉬움이 남는다.

 

 

[느낀 점]

한달 전 Winapi를 처음 접했을 시점에는 새로운 프레임워크에 당황하였고

유니티에서 쉽게 사용하던 것들을 사용하지 못하여 어려움이 있었으며

해당 기능들을 직접 구현하며 많은 것을 배울 수 있던 시간이었다.

 

+ Recent posts