-
남 넨마스터의 넨가드 스킬에 대한 고찰게임 클라이언트 개발/MakeDNF 2024. 1. 22. 19:44
최근 던전 앤 파이터의 현재 최상위 콘텐츠인 어둑 섬 해방 난이도에서 넨마스터의 무한 넨가드로 손쉽게 클리어하는 영상이 올라왔었다. 이에 직접 코드를 확인할 순 없지만 나름대로 왜 이런 상황이 발생하는지 추측해 보고자 한다.
넨가드 스킬
우선 넨가드란 어떤 스킬인지 확인해 보자. 넨가드란 남 넨마스터의 25 레벨에 습득할 수 있는 스킬로 (물론 여 넨마스터도 습득할 수 있다), 넨으로 보호구를 생성하여 자신을 포함하여 해당 영역에 존재하는 파티원도 무적으로 만드는 스킬이다. 여기서 키포인트는 "파티원을 무적으로 만든다"라는 문구이다. 던전 앤 파이터에선 캐릭터가 슈퍼아머 상태일 경우 캐릭터에 붉은빛 계열의 테두리가 생기며, 무적일 경우에는 하얀 테두리가 생긴다. 넨가드를 사용한 모습을 보면 캐릭터에 하얀 테두리가 생긴 것을 확인할 수 있다.
어둑 섬 콘텐츠에서 발생한 문제점
이제 어둑 섬 콘텐츠에서 발생한 무한 넨가드에 대해 알아보자. 해방 난이도는 딜량이 충분하더라도 패턴을 피하지못해 클리어하기 어려운 던전이다. 하지만 넨가드의 쿨타임을 최대한 줄여 계속해서 넨가드를 사용하여 패턴을 무시하고 클리어할 수 있다.
이에 대한 업데이트 공지 사항에는 "구조적으로 캐릭터를 타격하게 구현되어 있어 공격 대상에 쉴드가 포함되지 않는 문제가 있었습니다."라고 작성되있다.
문제 발생 원인 - 충돌 검사 로직
그렇다면 왜 이런 현상이 발생했을까에 대해 추측해보자. 위 공지사항에 적혀있는 내용을 확인하면, 해방 난이도의 라르고는 직접 타격형 공격과 오브젝트를 소환하여 공격하는 방식, 두 가지 방식으로 공격한다. 여기서 오브젝트를 소환하여 공격하는 방식이 바로 검은 선과 영역 공격이다. 던파는 2.5D 좌표계로 이루어져있으나 해당 공격들은 2D이기 때문에 기존 충돌 로직과 별개의 피격 판정 로직이 존재할 것으로 보인다.
/// <summary> /// Check whether the target has been hit. /// The target, passed as a parameter, is expected to the player list. /// The data structure of the parameter may be a list of players or a hash table with player unique IDs as keys /// </summary> public bool CalculateOnHit(List<IDamagable> targets) { if the target is out of attack range: return false; if the target is invincible: return false; return true; }
또한 런타임에 Hierarchy에서 피격 대상을 찾는 것은 굉장한 성능 이슈가 발생하므로 맵에 존재하는 오브젝트를 미리 변수로 저장했을 것으로 예상된다. 플레이어 캐릭터 리스트나, 플레이어가 소환한 소환수 오브젝틀 리스트, 혹은 몬스터 리스트와 같은 케이스를 나눠 미리 캐싱을 했을 것이다.
// Example of the room class for maintaining the targets in the room public class Room : MonoBehaviour { #region Variables private List<IDamagable> players = new(); private List<IDamagable> monsters = new(); private List<IDamagable> bossMonsters = new(); private List<IDamagable> namedMonsters = new(); private List<IDamagable> normalMonsters = new(); #endregion Variables #region Properties public List<IDamagable> Monsters => monsters; public List<IDamagable> BossMonsters => bossMonsters; public List<IDamagable> NamedMonsters => namedMonsters; public List<IDamagable> NormalMonsters => normalMonsters; #endregion Properties }
이제 피격 판정 로직으로 피격 대상을 파라미터로 전달할텐데, 이때 파라미터로 전달하는 타겟이 플레이어만 전달하는 것으로 보인다. 그렇기 때문에 넨가드 오브젝트는 피격 대상에 포함되지 않아 라르고의 공격에 피격되지 않으며, 데미지를 입지 않기 때문에 파괴되지도 않고, 라르고의 공격 범위 내에 캐릭터가 존재하더라도 넨가드 안에 있으면 무적 상태이기 때문에 피격되지 않는 판정이 되어 패턴을 무시할 수 있는 것으로 보인다.
그렇다면 넨가드 오브젝트도 같이 파라미터로 전달하면 되지 않냐라고 생각할 수도 있다. 아마 구조적으로 플레이어가 생성한 오브젝트를 표현하는 클래스가 구조적으로 소환수까지 포함하고 있지 않을까라는 생각이 든다. 만약 소환사 캐릭터가 해방 난이도를 플레이한다면, 검은 선과 영역 공격에 소환수들까지 피격될 것이고, 소환수들이 사망한다면 소환사 직업에 굉장한 불합리함을 줄 수 있을 것이다. 또한 충돌 체크 대상이 기하급수적으로 많아지기 때문에 그렇지 않아도 프레임 드랍을 유발하는 소환수의 불편한 플레이 경험이 배가 될 것으로 예상된다.
아마 "구조적으로 전반적인 문제 해결"이라는 문구가 넨가드와 같은 쉴드형 오브젝트와 소환수 오브젝트를 분리하기 위한 작업이라고 생각되며, 그렇기 때문에 시간이 걸리는 것 같다.
자료 출처 : 장지 유투브 https://www.youtube.com/watch?v=QVuOgZtD5gc&t=764s
'게임 클라이언트 개발 > MakeDNF' 카테고리의 다른 글
악즉참 스킬로 알아보는 역경직 발생 조건 (0) 2024.02.01 애니메이션과 스킬 타이밍 동기화, 근데 AnimatorStateInfo를 곁들인.. (0) 2024.01.31 Object Pooling을 위한 Tool 제작 (0) 2024.01.11 Hitbox와 Hitbox Editor 개선 (0) 2024.01.11 Skill 시스템 구현 및 개선 (0) 2024.01.10