-
Notifications
You must be signed in to change notification settings - Fork 0
Document
Moon edited this page Nov 7, 2023
·
9 revisions
프로젝트의 각 기능 구현 설명 Document 입니다.
- FTableRowBase, UDataTable, CSV파일 을 활용해 데이터 시스템을 구축했습니다.
- 게임 코드 수정 없이 게임 내 데이터 수정이 가능합니다.
- 방대한 양의 데이터를 코드와 분리합니다.
- csv와 UDataTable을 이용했습니다.
- 캐릭터 스탯이 캐릭터 타입 및 캐릭터 레벨에 따라 스탯이 달라지게 구현했습니다.
- 총기 스탯이 총기 타입 및 아이템 레벨에 따라 스탯이 달라지게 구현했습니다.
- 캐릭터 별로 에셋을 구분하고 쉽게 수정하기 위해 에셋 경로 데이터화
- 몬스터의 이동 경로를 데이터로 관리
- 스킬들은 공통 부모인
LSSkill
을 상속받아 구현했습니다. - 스킬들은 MP를 소모하며, MP가 부족하거나 쿨다운 중일 때는 시전되지 않게 했습니다.
- 수류탄 투척과 그래플링 훅을 구현했습니다.
- 스킬들은 플레이어의 컴포넌트인
LSSkillComponent
에 의해 관리됩니다.
- 조준 방향으로 그래플링 훅은 발사합니다.
- 그래플링 훅과 충돌하는 물체가 있다면 해당 물체 위치로 케이블 연결 후 캐릭터가 이동합니다.
- 조준 방향으로 수류탄을 투척합니다.
- 수류탄은 일정 시간 후에 터지며 범위 내 모든 몬스터들에게 데미지를 가합니다.
- 상호작용 가능한 물체들은 공통 부모인
ALSInteractableObject
를 상속받아 구현했습니다. - 아이템 박스
- 아이템 박스와 상호작용하여 아이템 획득합니다.
- 섹션
- 섹션 물체와 상호작용 시 레벨 내 섹션이 시작됩니다.
- 상호작용 가능한 물체 근처에 도달하면 상호작용 UI가 팝업됩니다.
- 상호작용 키를 누르고 있으면 상호작용 Progress Bar가 차오릅니다.
- 1초 동안 누르고 있으면 Progress Bar가 가득 차고, 상호작용이 완료됩니다.
- 플레이어의 스탯, 조준점, 장착 총기, 탄약 수 등을 나타냅니다.
- 관찰자 패턴을 이용해 HUD를 업데이트 하였습니다.
- HUD는 HP, Shield, 장착 총기, 탄약 수 등 게임 상태를 관찰하고, 게임 상태에 변경이 있을 시 업데이트하여 화면에 표시합니다.
- 언리얼 엔진의 Delegate을 이용해 구현했습니다. 관찰당하는 대상의 Delegate에 HUD의 업데이트 함수를 등록하고, 대상의 상태가 변경되면 Delegate가 호출되도록 했고 그에 따라 Delegate에 등록된 HUD의 함수도 같이 호출되도록 했습니다.
- 무기 등 장비를 전투 시작 전 강화할 수 있습니다.
드랍되는 아이템은 두 종류로 나뉩니다.
- 탄약, 골드, HP 회복 등의 아이템이 이에 해당합니다.
- Player와 collide 시 자동으로 룻 됩니다.
- 소지 한도를 초과하는 경우는 룻할 수 없습니다.
- 장비 가능한 아이템들이 이에 해당합니다.
- 아이템에 조준점을 두고 상호작용 키를 눌러야 획득 가능합니다.
-
UBTService
,UBTTaskNode
,UBTDecorator
, 블루프린트를 활용해 몬스터의 AI를 구현했습니다.
- Enhanced Input 을 이용하여 구현하였습니다.
- 선택한 이유
- 언리얼 엔진 5.1 버전부터 권장하는 Input 방식입니다.
- 플랫폼 별로 Input Mapping Context 를 달리해 설정이 가능합니다.
- 플레이어의 현재 상태에 따라 키 매핑을 다르게 하기 쉽습니다.
- 이전 입력 시스템과 호환되며, 다양한 입력을 구현해야 하는 대규모 게임에 적합하다고 알려져 있습니다.
FireRate 구현 과정
-
InputAction
의InputTrigger
를UInputTriggerPulse
로 설정했습니다.-
UInputTriggerPulse
는 Interval 초 단위로 트리거를 발동합니다.
-
-
UInputTriggerPulse
클래스는UInputTrigger
클래스를 상속하고 있으며, -
UInputAction
클래스는UInputTrigge
r들을TArray<TObjectPtr<UInputTrigger>>
로 보관하고 있습니다. -
UInputTriggerPulse
의 Interval에 접근해 무기의 FireRate를 설정하였습니다. - 인게임에서 무기 교체 등에 따라 FireRate가 달라지면 Interval도 그에 맞게 수정해 주어야 합니다.
- 코드에서 Interval에 접근하기 위해
UInputTrigger
포인터를UInputTriggerPulse
포인터로 캐스트해 접근했습니다.
static ConstructorHelpers::FObjectFinder<UInputAction> IA_SHOOT(TEXT("/Game/LS/Input/Actions/IA_SHOOT.IA_SHOOT"));
if ( IA_SHOOT.Succeeded())
{
ShootAction = IA_SHOOT.Object;
// check nullptr
LSCHECK(ShootAction->Triggers.Num() > 0);
TObjectPtr<UInputTriggerPulse> InteractInputTrigger = Cast<UInputTriggerPulse>(ShootAction->Triggers[0]);
// check nullptr
LSCHECK(nullptr != InteractInputTrigger);
InteractInputTrigger->Interval = FireRate;
}
- 얻은점
- 온라인 상 자료가 많지 않아 사용하기 위해 소스코드를 분석할 기회가 되었습니다.
- 그 과정속에서 엔진이 Enhanced Input을 어떻게 구현했는 지 구조를 알 수 있었고,
- 포인터 캐스트를 통해 자식 클래스의 멤버에 접근하는 방법을 익힐 수 있었습니다.
- 성능 및 관리를 위해
UObject
형태로 아이템들을 보관합니다.
- 무기, 장신구, 모듈 등이 있습니다.
- 씬에 표현되어야 하는 무기는 액터로 구현합니다.
- 성능 향상을 위해 무기 장착 해제시에는 액터를 파괴합니다.