Skip to content

Document

Moon edited this page Nov 7, 2023 · 9 revisions

프로젝트의 각 기능 구현 설명 Document 입니다.



1. 데이터 시스템

코드 링크

1-1. 내용

  • FTableRowBase, UDataTable, CSV파일 을 활용해 데이터 시스템을 구축했습니다.
  • 게임 코드 수정 없이 게임 내 데이터 수정이 가능합니다.
  • 방대한 양의 데이터를 코드와 분리합니다.

1-2. 구현 사항

  • csv와 UDataTable을 이용했습니다.
  • 캐릭터 스탯이 캐릭터 타입 및 캐릭터 레벨에 따라 스탯이 달라지게 구현했습니다.
  • 총기 스탯이 총기 타입 및 아이템 레벨에 따라 스탯이 달라지게 구현했습니다.

1-3 추가 구현할 사항

  • 캐릭터 별로 에셋을 구분하고 쉽게 수정하기 위해 에셋 경로 데이터화
  • 몬스터의 이동 경로를 데이터로 관리

2. 스킬

코드 링크

2-1. 내용

  • 스킬들은 공통 부모인 LSSkill을 상속받아 구현했습니다.
  • 스킬들은 MP를 소모하며, MP가 부족하거나 쿨다운 중일 때는 시전되지 않게 했습니다.

2-2. 구현 사항

  • 수류탄 투척과 그래플링 훅을 구현했습니다.
  • 스킬들은 플레이어의 컴포넌트인 LSSkillComponent에 의해 관리됩니다.

2-2-1. 그래플링 훅

GrapplingHook

  • 조준 방향으로 그래플링 훅은 발사합니다.
  • 그래플링 훅과 충돌하는 물체가 있다면 해당 물체 위치로 케이블 연결 후 캐릭터가 이동합니다.

2-2-2. 수류탄 투척

  • 조준 방향으로 수류탄을 투척합니다.
  • 수류탄은 일정 시간 후에 터지며 범위 내 모든 몬스터들에게 데미지를 가합니다.

3. 상호작용

코드 링크

3-1. 내용

  • 상호작용 가능한 물체들은 공통 부모인 ALSInteractableObject를 상속받아 구현했습니다.
  • 아이템 박스
    • 아이템 박스와 상호작용하여 아이템 획득합니다.
  • 섹션
    • 섹션 물체와 상호작용 시 레벨 내 섹션이 시작됩니다.

3-2. 구현 사항

  1. 상호작용 가능한 물체 근처에 도달하면 상호작용 UI가 팝업됩니다.
  2. 상호작용 키를 누르고 있으면 상호작용 Progress Bar가 차오릅니다.
  3. 1초 동안 누르고 있으면 Progress Bar가 가득 차고, 상호작용이 완료됩니다.

interact1 interact2


4. HUD

코드 링크

  • 플레이어의 스탯, 조준점, 장착 총기, 탄약 수 등을 나타냅니다.

관찰자 패턴

  • 관찰자 패턴을 이용해 HUD를 업데이트 하였습니다.
  • HUD는 HP, Shield, 장착 총기, 탄약 수 등 게임 상태를 관찰하고, 게임 상태에 변경이 있을 시 업데이트하여 화면에 표시합니다.
  • 언리얼 엔진의 Delegate을 이용해 구현했습니다. 관찰당하는 대상의 Delegate에 HUD의 업데이트 함수를 등록하고, 대상의 상태가 변경되면 Delegate가 호출되도록 했고 그에 따라 Delegate에 등록된 HUD의 함수도 같이 호출되도록 했습니다.

5. 강화

  • 무기 등 장비를 전투 시작 전 강화할 수 있습니다.

enhancement


6. 아이템 룻

코드 링크

itemloot

드랍되는 아이템은 두 종류로 나뉩니다.

6-1. 자동 룻 아이템

  • 탄약, 골드, HP 회복 등의 아이템이 이에 해당합니다.
  • Player와 collide 시 자동으로 룻 됩니다.
  • 소지 한도를 초과하는 경우는 룻할 수 없습니다.

6-2. 선택 룻 아이템

  • 장비 가능한 아이템들이 이에 해당합니다.
  • 아이템에 조준점을 두고 상호작용 키를 눌러야 획득 가능합니다.

7. AI

코드 링크

  • UBTService, UBTTaskNode, UBTDecorator, 블루프린트를 활용해 몬스터의 AI를 구현했습니다.

BT


8. 입력

Enhanced Input

  • Enhanced Input 을 이용하여 구현하였습니다.
  • 선택한 이유
    • 언리얼 엔진 5.1 버전부터 권장하는 Input 방식입니다.
    • 플랫폼 별로 Input Mapping Context 를 달리해 설정이 가능합니다.
    • 플레이어의 현재 상태에 따라 키 매핑을 다르게 하기 쉽습니다.
    • 이전 입력 시스템과 호환되며, 다양한 입력을 구현해야 하는 대규모 게임에 적합하다고 알려져 있습니다.

주요 구현

FireRate 구현 과정

  • InputActionInputTriggerUInputTriggerPulse 로 설정했습니다.
    • UInputTriggerPulse는 Interval 초 단위로 트리거를 발동합니다.
  • UInputTriggerPulse 클래스는 UInputTrigger 클래스를 상속하고 있으며,
  • UInputAction 클래스는 UInputTrigger들을 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을 어떻게 구현했는 지 구조를 알 수 있었고,
    • 포인터 캐스트를 통해 자식 클래스의 멤버에 접근하는 방법을 익힐 수 있었습니다.

9. 인벤토리

  • 성능 및 관리를 위해 UObject 형태로 아이템들을 보관합니다.

10. 장비

  • 무기, 장신구, 모듈 등이 있습니다.
  • 씬에 표현되어야 하는 무기는 액터로 구현합니다.
    • 성능 향상을 위해 무기 장착 해제시에는 액터를 파괴합니다.