Elven Ring
Elden ring 모작 프로젝트
Elden ring 모작 프로젝트
스팀의 Elden Ring을 모작한 멀티플레이 기반 액션 롤플레잉 장르의 프로젝트입니다.
보스 AI 구현을 담당했으며, 총 3종의 보스를 설계했습니다. 각 보스는 **등장, 페이즈 전환, 사망 시퀀스(Level Sequence)**를 포함하고 있으며, 다양한 공격 패턴과 상태 전이 로직을 구현했습니다.
또한 멀티플레이 환경에서도 안정적으로 동작하도록, 플레이어별 누적 피해량을 기반으로 보스가 동적으로 타겟을 선택하는 시스템을 구현했습니다.
개발 환경
C++, Unreal Engine
개발 인원
개발 5
Steam
-----------
1. Artorias 보스 구현
(1) 피격, 공격 판정
Capsule Collision으로 보스의 피격 판정
검의 Skeletal Mesh에 추가한 Socket에 Capsule Collision을 부착하여 공격 판정
해당 콜리전에 Overlap된 플레이어는 데미지를 받은 후 TArray에 추가됨
TArray에 포함된 플레이어는 Overlap 되어도 데미지를 받지 않음
공격 애니메이션 종료시 TArray 초기화
(2) Level Sequence 구현
Spawn Level Sequence
카메라 줌/인 아웃 기능을 활용하여 몰입감 연출
Dead Level Sequence
Niagara System과 Material을 활용하여 Dissolve 효과 구현
(3) 공격 패턴 구현
찌르기 공격 패턴
플레이어와 보스 사이의 거리가 일정 거리 이상인 경우 찌르기 패턴 출력
AddMovementInput으로 바라보는 방향으로 전진하도록 구현
점프 공격 패턴
플레이어와 보스 사이의 거리가 일정 거리 이상인 경우 점프 공격 출력
플레이어를 바라보는 방향 벡터를 계산
플레이어와 보스 사이의 거리를 계산
Jump 가상 메서드를 활용하여 해당 방향으로 점프하는 느낌으로 이동하도록 구현
착지 시 Camera Shaking 출력
일반 공격 패턴 1 (내려찍기)
일반 공격 패턴 2 (휘두르기)
일반 공격 패턴 3 (구르기)
일반 공격 패턴 4 (회전 휘두르기)
공격 애니메이션의 특정 타이밍에 Notify를 호출하여 공격 Collision을 활성화
일반 공격 패턴은 플레이어와 일정 거리 이내일 시 랜덤으로 출력하는 구조로 구현
2. Tenebris 보스 구현
(1) 피격, 공격 판정
Skeletal Mesh의 Physics Asset으로 공격, 피격 판정
(2) Level Sequence 구현
Spawn Level Sequence
Socket에 카메라를 Attach하여 생동감 있는 연출 구현
Phase Level Sequence
Texture의 Base Color의 RGB 값을 조정함으로써 강해지는 느낌 연출
Dead Level Sequence
카메라가 화면에서 멀어짐으로써 끝나는 느낌 연출
(3) 공격 패턴 구현
브레스 공격 패턴
1페이즈 시작 시 출력되도록 구현
입에 추가한 Socket에서 Bress Niagara System을 출력
해당 Collision과 Overlap 시 데미지를 받도록 구현
점프 공격 패턴
2페이즈 시작 시 출력되도록 구현
입에 추가한 Socket에서 FireBall Niagara System을 출력
Socket에서 플레이어를 바라보는 방향벡터를 계산
해당 방향벡터로 이동하도록 구현
Earthquake 패턴
Speical Attack Interval마다 출력되도록 구현
바닥에 닿는 순간 주변에 플레이어가 Overlap 되는지 확인
일반 공격 패턴 1 (내려찍기)
일반 공격 패턴 2 (휘두르기)
공격 애니메이션의 특정 타이밍에 Notify를 호출하여 공격 Collision을 활성화
일반 공격 패턴은 플레이어와 일정 거리 이내일 시 랜덤으로 출력하는 구조로 구현
4. 보스 상태 패턴 구현
(1) BossStateInterface.h
인터페이스 기반 상태 패턴 구조로, OnStateEnter, OnStateUpdate, OnStateExit 세 함수를 통해 보스의 상태 전이(진입–유지–종료)를 명확히 분리하여 관리할 수 있음.
Unreal의 UInterface와 C++ pure virtual 함수(=0)를 결합해 블루프린트와 C++ 양쪽에서 구현 가능한 확장성 높은 설계를 제공함.
(2) Boss.h
Boss.cpp
구현 방식 및 특징
Behavior Tree를 사용하지 않고, C++ 레벨에서 상태 패턴(State Pattern) 직접 구현
Idle, Move, Attack 등의 상태를 독립적인 클래스로 분리하여 설계
상태별 로직이 명확하게 분리되어 코드의 유지보수성과 가독성 향상
단점으로, Behavior Tree처럼 AI 상태 전환 조건을 유동적으로 변경하기는 어려움
5. 보스 패턴 출력 시스템
(1) UBossPatternComponent.h
보스의 공격 패턴을 관리하는 Actor Component를 구현
AddAttackPattern을 호출하여 패턴을 저장하고, ExecuteAttackPattern을 호출하여 랜덤한 패턴을 출력하는 방식
문제점
문제 상황
UStageSubSystem에서 LoadObject()를 통해 DataTable을 런타임에 직접 로드하도록 구현
에디터 상에서는 정상적으로 참조 유지되었으나 Shipping 빌드 패키징 후에는 DataTable 참조가 손실되는 문제 발생
원인 분석
LoadObject( ) 방식은 패키징 시 리소스가 강제로 포함되지 않기 때문에, 참조된 DataTable이 빌드 결과물에 누락될 수 있음
즉, 하드 레퍼런스가 아닌 런타임 동적 로드 방식으로 인해 참조 보장이 이루어지지 않음
LoadObject 소드 코드
개선 방향
해결 방법
Primary Asset Label을 활용하여 DataTable을 Primary Asset으로 등록
해당 라벨을 통해 패키징 시 리소스가 강제로 포함되도록 보장
결과
에디터 / Shipping 빌드 모두에서 참조 일관성 확보
런타임 환경에서도 안정적으로 DataTable 로드 및 접근 가능
Primary Asset Label
문제점
문제 상황
튜토리얼 전용 HUD를 다른 레벨에서도 참조함
그 결과, 각 레벨의 Size Map이 약 600MB씩 불필요하게 증가하는 문제 발생
원인 분석
모든 레벨에서 공통으로 사용하는 PlayerController가 HUD를 소유하는 구조로 구현되어 있었음
HUD가 하드 레퍼런스로 연결되어 있어, 사용하지 않는 레벨에서도 리소스가 포함됨
하드 레퍼런스로 인한 SizeMap 과부하 현상
회고 및 개선 방향
해결 시도 및 대안
공통 기능은 부모 PlayerController에 두고 튜토리얼 전용 기능은 자식 TutorialController로 분리하는 방식으로 해결 가능성을 검토
그러나 시간 제약으로 구조적 수정은 진행하지 못함
배운 점
PlayerController의 상속 구조 설계의 중요성을 인식함
**하드 레퍼런스(Strong Reference)**와 **소프트 레퍼런스(Soft Reference)**의 차이를 이해하고 리소스 관리 방식 개선의 필요성을 체감함
부트캠프 언리얼 트랙 우수 프로젝트 선정