전투 파트의 구현에는 중재자 패턴, 옵저버 패턴, 싱글턴 패턴을 사용했습니다.
데미지 계산은 중재자 패턴을 이용했으며, 애니메이션 간의 데이터 교환은 옵저버 패턴을, 그리고 종합적인 전투 프로세스 제어에는 싱글턴 패턴을 이용했습니다.
다만, 아직 완전한 전투 시스템 구현은 아닌 상태이며,
보완할 부분이 있다고 생각합니다.

캐릭터의 스킬 공격과 평타 공격은 상단의 SwordFunction 클래스로부터 시작됩니다.
해당 클래스는 OnTriggerEnter가 함수가 구현되어, 콜라이더의 충돌을 감지할 수 있으며, 플레이어의 검 오브젝트에 부착된 콜라이더를 이용해, Monster 레이어를 판정하고 상속 받은 중재자 패턴을 통해 데미지 함수를 호출합니다.

몬스터의 공격 판정은 위 그림의 MonsterAtkColliderMng 클래스로부터 시작됩니다.
마찬가지로 OnTriggerEnter를 통해서, 콜라이더의 충돌을 감지하고 충돌체가 Player 레이어에 해당할 경우에, 중재자 패턴을 통해서 데미지 계산 함수를 호출합니다.
다만, 몬스터의 경우에는 오브젝트 풀을 이용해서 주기적으로 활성화/비활성화되기 때문에, GameManager에 OnPauseStateChanged 이벤트를 구독하고 해제해줍니다.
이때, OnPauseStateChanged 객체는 플레이어가 특정 UI 창을 열었을 때, 게임의 time이 일시정지 될 때를 알리고, 정적 함수인 HandlePauseStateChanged() 함수를 호출하여, Time.timeScale 값을 제어하는 함수입니다.
캐릭터 평타 공격은, 원소 속성을 이용하지 않은 단순 물리 공격입니다.
칼을 휘두르는 애니메이션에 프레임 단위로 콜라이더를 이동시켜, 칼의 이동경로에 충돌을 판정할 수 있도록 하였습니다.



이러한 평타 공격은 애니메이션1~3까지 존재하며,
파트 1에서 설명했던 캐릭터 어택 매니저에서 AttackLevel 변수의 값에 따라서, 공격을 연속해서 진행할 수 있도록 하였습니다.
공격 버튼 클릭으로 공격 애니메이션 호출 → 애니메이션 동작 및 Sword_Collider 박스 활성화 → 콜라이더 박스에 몬스터 충돌 했을 경우, → OnTriggerEnter → Mediator_CharacterAttack → 콜라이더 박스 SetFalse → 공격 버튼 연속 클릭 == true → 다음 레벨의 공격 동작

데미지 계산은 부분은 직접적으로 캐릭터의 공격이 몬스터에게 데미지를 주는 부분입니다.
그렇기 때문에, 몬스터 클래스의 데이터와 캐릭터 클래스의 데이터가 모두 필요합니다.
몬스터를 총괄하는 MonsterManager 클래스를 매개변수로 받습니다.
그리고 몬스터의 체력 감소를 UI(HP바)로 표시하기 위해서, 관련 함수를 호출합니다.
이러한 몬스터 HP바의 증감에 대한 실질적인 작용은 MonsterHp 클래스에서 이뤄지며, Init 함수 호출 후 → HpBarFill_End 함수를 호출하는 것으로, 데미지 계산 전 체력과, 데미지 계산 후 체력을 비교하여 감소한 양만큼을 러프하게 깎아줍니다.
데미지 계산은 다음과 같습니다.
1. 크리티컬 데미지 반영 여부 계산 => 크리티컬 확률값을 이용하여 bool형으로 저장.
2. 캐릭터의 공격력 - 캐릭터의 방어력.
3. 계산 결과, 데미지가 음수라면, 음수 값을 반영하지 않고 그대로 리턴.
4. 크리티컬 데미지 계산 => 캐릭터의 데미지를 기준으로 캐릭터 크리티컬 데미지 값에 해당하는 수치를 백분율로 보정함.
5. 크리티컬 반영 여부에 따라서 데미지 값을, 추가.
6. 실제적으로 몬스터의 HP에 데미지 만큼 체력을 감산.
이외에도 필요한 UI 작업은, DamageTextManager 클래스를 호출하여, 데미지값을 숫자 형태로 출력하도록 하는 것이 있습니다.
캐릭터의 스킬 또한, 공격의 파정 포인트는 검에 부착된 콜라이더 박스입니다.
캐릭터의 공격 단계를 구분짓는 atkLevel 변수를 이용하여 현재 동작 중인 애니메이션과 공격이 일반 공격인지 스킬 공격인지 판정합니다.
만약 공격 단계가 e_AttackLevel.AtkSkill에 해당한다면 스킬로 판정 후, 해당 함수를 호출합니다.

평타 공격과 마찬가지로, 애니메이션 동작의 프레임 사이사이에 콜라이더의 위치를 조정하여, 박스 콜라이더가 매끄럽게 검을 따라갈 수 있도록 하였습니다.
데미지 계산 파트 역시 중재자 패턴을 통해서 이뤄집니다.
다만, 평타 공격과는 다르게 스킬 공격은 현재 캐릭터의 원소 상태에 따른 속성 공격이기 때문에, 현재 원소 상태에 따른 분기와 원소 반응에 따른 개별 효과가 구현되어야 합니다.
이러한 원소 반응 역시 모작의 모태가 되는 원신의 원소 반응을 구현하는 방향으로 했습니다.

이러한 원소 반응은 정적 클래스인 Element_Interaction에 의해서 관리됩니다.
캐릭터의 현재 원소를 기준으로 swich 문으로 분기하여, 현재 적의 원소 상태에 따라서, 원소 효과를 일으킵니다.
만약, 적에게 아무 원소도 부착되어 있지 않다면, 원소를 묻히고 데미지를 주는 것으로 대신합니다.


캐릭터 속성 - 화염 속성
적 속성 - 원소 없음 => 화염 원소 부착.
적 속성 - 물 원소 => c_FireToWater()
ㄴ 데미지 보정
적 속성 - 풀 원소 => c_FireToPlant()
ㄴ 지속 데미지
적 속성 - 번개 원소 => c_FireToLightning(), c_FireToLightningGetDamage()
ㄴ 원소 확산
적 속성 - 바람 원소 => c_FireToWind(), c_FireToWindGetDamage()
ㄴ 원소 확산
각 원소 상태에 따른 분기는 위와 같습니다.
로직의 흐름을 크게 파악해보자면, 함수를 호출하는 데 필요한 매개변수를 위한 변수들을 인스턴스화 하여 선언하고,
hp바 반영을 위해서 HpBarFill_Init 함수를 호출합니다.
이후, 타겟이 된 몬스터와 플레이어 캐릭터의 각 원소 상태를 Get 하여 비교 후, 알맞는 함수를 호출합니다.


캐릭터 속성 - 물 속성
적 속성 - 원소 없음 => 물 원소 부착.
적 속성 - 불 원소 => c_WaterToFire()
ㄴ 데미지 보정
적 속성 - 풀 속성 => c_WaterToPlant()
ㄴ 풀 원핵 생성
적 속성 - 번개 원소 => c_WaterToLightning(), c_WaterToLightningGetDamage()
ㄴ 원소 확산
적 속성 - 바람 원소 => c_WaterToWind(), c_WaterToWindGetDamage()
ㄴ 원소 확산
물 원소의 특이점은 풀 원소와 공명하여 풀 원핵을 생성한다는 것입니다.
자세한 설명은 원소 반응 파트에서 설명하겠지만, 물 원소와 풀 원소는 서로 반응하여 필드 상에 풀 원핵을 생성합니다.
이렇게 생성된 풀 원핵은, 특정 원소와 결합하여 추가 원소 반응을 이끌어낼 수 있습니다.


캐릭터 속성 - 풀 원소
적 속성 - 속성 없음 => 풀 원소 부착.
적 속성 - 불 원소 => c_PlantToFire()
ㄴ 일정 시간 데미지
적 속성 - 물 원소 => c_WaterToPlant()
ㄴ 풀 원핵 생성
적 속성 - 번개 속성 => c_LightningToPlant()
ㄴ 상태 이상 부여
적 속성 - 바람 속성 => c_PlantToWind(), c_PlantToWindGetDamage()
ㄴ 원소 확산
풀 원소와 불 원소가 만나면 지속 데미지를, 그리고 물 원소와 반응 시 풀 원핵 생성을 합니다.
번개 속성과 만날 시에는 상태 이상을 적에게 걸어 주며, 바람 원소는 다른 원소와 마찬가지로 풀 원소를 주위의 적에게 묻히게 하는 확산기능을 갖습slek.


캐릭터 속성 - 번개 원소
적 속성 - 속성 없음 => 번개 원소 부착
적 속성 - 불 원소 => c_LightningToFire(), c_LightningToFireGetDamage()
ㄴ 원소 확산
적 속성 - 물 원소 => c_LightningToWater()
ㄴ 지속 데미지
적 속성 - 풀 원소 => c_LightningToPlant()
ㄴ 상태 이상 부여
적 소성 - 바람 원소 => c_LightningToWind(), c_LightningToWindGetDamage()
ㄴ 원소 확산
번개 원소는 기존의 원소 반응 함수와 비슷합니다.
각 원소에 반응하여, 확산, 지속 데미지, 상태 이상 부여, 원소 확산의 효과를 이끌어 냅니다.


캐릭터 원소 - 바람 원소
적 원소 - 원소 없음 => 바람 원소 부착
적 원소 - 원소 있음 => 각 원소의 확산
바람 원소는 원소를 확산 시켜, 부착되어 있는 원소를, 혹은 부착할 원소를 주변의 적에게 뿌리고 데미지를 줍니다.
다만, 이렇게 확산되어 주변의 적에게 원소를 부착한 경우에는 데미지를 반감하여 주게 됩니다.
각 원소의 반응에 따라 분기 하여, 함수를 호출하고 값을 얻어낸 후에,
해당 원소 반응이 확산일 경우에는 DiffusionFunc() 함수가 호출됩니다.


확산 범위 만큼 OverlapSphere 메서드를 이용하여, 범위 내의 적들에게 피해량과 피해 보정값을 이용하여 데미지를 주고 원소 타입을 매개 변수로 받아서 원소를 부착 시키고, 데미지를 줍니다.
스킬의 원소 반응을 담당하는 클래스인 정적 클래스 Element_Interaction는 static의 형태로, 맴버 메서드를 제공하거나, 싱글턴을 통해서 메서드를 제공합니다.
이는, 모노비헤이비어의 생명 주기를 필요로하는 메서드가 존재하기 때문입니다.
일정 시간 동안 데미지를 주거나, 디버프를 유지하는 기능을 구현하기 위해서 코루틴을 이용해야 하지만, 정적(static) 멤버 메서드에서 코루틴을 직접 구현하는 것은 불가능합니다.
이때문에, 필요에 따라서 싱글턴 패턴을 통해서, 맴버 메서드에 접근하도록 구현하거나 정적 메서드를 통해서 함수를 호출할 수 있도록 구현했습니다.

공통적으로 사용되는 치명타 계산 함수는 다음과 같습니다.
치명타 확률을 기반으로 크리티컬 반영 여부를 결정하고, 데미지의 배율을 적용하여 치명타 데미지 값을 구합니다.
이렇게 구한 치명타 데미지 값을 데미지에 반영하거나, 무시하거나를 isCritical 변수에 의거하여 결정합니다.

몬스터에 부착되어 있는 원소가 존재하지 않을 때, 호출되는 함수입니다.
몬스터 객체의 hittedElement를 인스턴스화하여, 캐릭터의 현재 원소 상태를 반영하고, SetActive하여 활성화합니다.
또한, 데미지 계산을 돌려 최종적으로 몬스터에게 피해를 줄 데미지량을 리턴합니다.
다만, 이 때 몬스터가 풀+번개의 조합으로인해서 격화 상태에 빠져있는 경우엔, 데미지 량을 보정하여, 플레이어 캐릭터의 원소 마스터리 값의 1.2배에 해당하는 데미지를 추가로 더합니다.

불-물 반응은 50%만큼 데미지 증가입니다.
크리티컬 데미지 함수에 증가하는 데미지 값을 오프셋으로 넣어서 데미지 값을 반환 받습니다.
그리고, 해당 값에 몹의 방어력을 감산하여 최종 데미지를 리턴합니다.

불-번개의 경우에는 확산할 범위와 데미지를 구해야합니다.
범위는 캐릭터의 원소 마스터리에 영향을 받으며, 데미지는 캐릭터의 공격력에 영향을 받습니다.




불-풀의 원소 반응은 일정시간 동안 도트 데미지를 주는 반응입니다.
캐릭터의 원소 마스터리를 이용하여, 지속 피해 시간과 데미지를 구하고 이렇게 구한데미지 값을 코루틴 함수로 돌려서 일정 시간 동안 데미지를 줍니다.
CalculateDamageOverTime() 함수의 경우에, 불-풀 원소 반응 뿐만 아니라 지속 시간 데미지를 주는 모든 로직에 사용되기에, 속성별로 다른 색상의 데미지 플로팅 문자를 출력하도록 해줍니다.

불-바람 원소 반응은 불-번개와 동일합니다.
원소 마스터리에 의거하여, 확산 범위를 리턴하고 CiriticalDamageReturn()함수를 이용하여 데미지 값을 얻습니다.

물-불 원소 반응은 불-물 반응과 동일하지만, 공격력의 100%만큼 추가 데미지를 준다는 점에서 차이가 있습니다.

물-번개의 원소 반응 또한, 불-번개 and 불-바람과 마찬가지로 확산과 데미지라는 형식의 데미지 구조입니다.
다만 확산 특화인 바람 원소 반응보다는 확산 범위가 작고, 반대로 불-번개의 반응 보다는 확산 범위가 넓은 것이 특징입니다.


물-풀의 원소 반응은 조금 복잡합니다.
원신의 원소 반응 로직을 본따서, 풀원핵을 필드에 생성하고 최대 생성 가능 숫자를 벗어났을 경우, 차례대로 원핵이 터지며, 주위의 적에게 데미지를 줍니다.
이 과정에서 플레이어가 특정 원소(화염 or 번개)로 공격했을 경우에는, 원핵이 터지며 원소 반응을 일으킵니다.

풀 원핵의 주위에 캐릭터의 원소 반응이 일어났을 경우에, 호출되는 함수입니다.
화염 속성의 경우에는 FireToPlant 함수를 호출하여, 지속데미지를 주며,
번개 속성과 원소 반응할 경우, 격화 상태를 부여합니다.

바람 속성의 원소 반응은 상단의 화염-바람과 동일합니다.
확산 범위를 리턴하고, 데미지를 반환하여 리턴.
이후, CombatMediator 클래스에서 DiffusionFunc() 함수를 이용해서, 원소 확산 및 데미지를 부여.

번개-불 원소의 확산 반응은 상단의 확산 범위 반환-데미지 반환 로직과 구조적으로 동일하기에 생략하겠습니다.

번개-물의 경우에는
화염-풀에서 구현한 CalculateDamageOverTime() 함수를 이용한, 지속시간 데미지를 구현했습니다.
공격력에 기반으로 한 지속 피해 시간과 데미지 값을 이용한다는 점에서 불-풀과는 차이가 있습니다.

번개-바람은 생략하도록 하겠습니다.

번개-풀 속성의 반응은 격화를 일으킵니다.
몬스터가 보유한 isQuicken 변수를 수정하여 몬스터에게 상태이상을 부여합니다.
격화 상태가 된 몬스터는 원소부착 및 데미지 반환 기능을 담당하는 c_ElementSet() 함수 단계에서 데미지를 크게 받게 됩니다.
// 몬스터가 격화 상태라면, 촉진/발산 효과로 원소량에 따라 데미지 증가.
if(targetMob.GetIsQuicken()==true)
{
if (chCls.GetCurrnetElement().GetElement() == Element.e_Element.Lightning ||
chCls.GetCurrnetElement().GetElement() == Element.e_Element.Plant)
damage += (int)(chCls.GetElementNum() * 1.2f);
}
단 풀원소 혺은 번개 원소에 반응하여 데미지가 증가됩니다.

여타 속성과 다르게 풀 속성은 풀속성과도 원소반응을 일으킵니다.
위 코드는 물-풀에서 구현한, 풀원핵 과다 생성 단계에서 사용되며, 원소 마스터리 값에 의거하여, 데미지 값을 반환하는 기능을 가지고 있습니다.
int damage = c_PlantToPlant(chCls, mobCls); // 개화 데미지 계산 함수 호출
int mobHp = mobCls.GetMonsterCurrentHp();
mobCls.SetMonsterCurrentHP(mobHp - damage); // 몬스터 체력 감소
덧붙여, 기존의 몬스터의 피격 원소 속성을 제거하고 풀속성을 붙입니다.

풀-불 원소의 경우에는
대상이 되는 단일 타겟에게는 일정 시간 데미지 부여를 하고,
여기에 더해 원소 범위 확산 반응을 일으켜, 주위의 적에게 풀원소 상태를 부여하게 합니다.
바람 원소의 경우, 기존의 원소 반응에서 구현했던 원소-바람 반응의 로직을 재활용했기에 스킵했습니다.
0.4만큼의 범위에 원소를 확신시키고, 주위의 적에게 50%로 반감한 데미지 값을 주며, 대상 타겟에ㅔ는 100% 만큼의 데미지를 줍니다.
몬스터의 공격은 몬스터의 타겟 범위를 찾는 ViewRange 내에 적이 탐지 되었을 경우에, 옵저버 패턴으로 어택 매니저에 알리고 이에 따라 공격 애니메이션 패턴으로 진입하여 이뤄집니다.


몬스터의 공격은 몬스터의 전방에 위치한 콜라이더 박스를 이용하는 것으로 구현되며, 박스에 캐릭터가 존재할 경우에, 충돌 판정을 얻고 중재자 패턴으로 데미지 계산 함수를 호출합니다.

몬스터의 공격도 캐릭터의 공격과 유사하게 몬스터가 원소를 가지고 있는지의 여부에 따라서 원소 공격을 하거나, 아니면 일반 물리 공격을 하거나로 나뉘게 됩니다.
다만, 몬스터가 구현하는 원소 공격은 캐릭터에게 적용되는 원소 공격과는 약간 다른 부분이 존재합니다.

이러한 원소 반응 효과는 캐릭터와 마찬가지로 Element_Interaction클래스에 구현되어, static을 이용하여, 정적 메서드에 접근하여 구현됩니다.
이때, 각 원소 반응은 캐릭터에 중독된 원소 상태를 기준으로 스위치문으로 분기합니다.



캐릭터의 원소 중독 상태가 NONE이라면, 몬스터가 보유한 원소를 부착시킵니다.
이미 원소를 얻은 상태라면, 캐릭터의 현재 원소 + 몬스터의 원소가 반응되어, 각 조건에 맞는 원소 공격이 부여됩니다.
이러한 원소 데미지 공식에 의거하여, 얻은 damage값만큼 캐릭터의 체력을 깎는 것으로 로직을 종료합니다.
또한 원소 공격 유무를 bool형으로 반환합니다. 이는, 추후 구현할 캐릭터 스턴이나 경직에 이용할 예정입니다.
화염 속성(Fire)

화염 속성에 의한 원소 반응은 선 방감산 이후 데미지를 증폭시킵니다.
캐릭터의 원소 상태를 제거하고, 각 속성에 따라서 보정된 데미지를 리턴합니다.
각 보정값은 아래와 같습니다.
화염 + 물 = 150%의 데미지
화염 + 번개 = 120%의 데미지
화염 + 풀 = 200%의 데미지

물 속성은 화염 속성과는 반대로 선 데미지 증폭 후, 방어력 감산이 이뤄집니다.
또한 화염 속성과 마찬가지로, 캐릭터에 부착되어 있는 원소 상태를 제거합니다.
각 보정값은 아래와 같습니다.
물 + 화염 = 150%
물 + 번개 = 120%
물 + 풀 = 130%

번개 속성은 기본적으로 높은 데미지를 보장하나, 캐릭터의 방어력에 마이너스 연산이 아닌, 비례 연산에 의거하여 데미지가 깎입니다.
즉, 플레이어의 방어력이 높으면 높을 수록 미비한 데미지를 받게 되며, 방어력이 낮다면 큰 피해를 입게 됩니다.
또한 마찬가지로 플레이어에 부착된 원소를 제거합니다.
각 보정값은 아래와 같습니다.
번개 + 화염 = 270%
번개 + 물 = 240%
번개 + 풀 = 300%

풀 속성 원소 반응은 방어력 무시 데미지입니다.
그렇기 때문에, 플레이어는 방어력을 높이기 보다는, 체력을 높이는 쪽이 더 효과적으로 대응할 수 있을 것입니다.
마찬가지로 플레이어에 부착된 원소를 제거합니다.
각 보정값은 아래와 같습니다.
풀 + 화염 = 140%
풀 + 물 = 100%
풀 + 번개 = 110%

바람 속성의 컨셉은 속성 변환입니다.
즉, 플레이어가 바람 속성이 묻어있다면, 부착되어 있는 캐릭터의 바람 원소를 지우지 않습니다.
오히려 몬스터의 원소를 붙이는 것으로 속성을 변환시킵니다.
이는, 다음 속성의 원소반응을 빠르게 일으켜, 플레이어의 피해를 누적시킬 수 있을 것입니다.
또한, 바람 속성은 공통적으로 110%의 보정된 데미지값을 줍니다.
이때, 방어력의 감산은 선제적으로 이뤄지며, 감산된 결과값을 기준으로 110% 보정을 줍니다.