1. 오늘의 목표
리팩토링 완료 후 Character.cs 와 배틀로직이 있는 Monster.cs와 연결
2. 작업 개시🛠️
일단, 리팩토링부터 마저하기로 한다.
어제 만들어둔 구조를 토대로 반복수행하면 된다.
하지만 반복수행이라고 써도 디테일은 다르니 디테일은 살리도록 하자.
1. 나와라 Json
Q. 갑자기 json?
A. 저거 일일히 코드를 치고 있으니까 눈도 어지럽고 헷갈리길래 json으로 바꿨다.
json도 사실 그냥은 만들 엄두가 안나서 exel에 입력 후 바꿨다. 엑셀 짱.
스킬을 불러와줄 Loader 함수, 담아둘 Factory 등등...을 만들어두었지만, 이거까지 다 쓰려면 머리가 아프다.
뿐만 아니라, 일단 필요하다니까 긁어온 것에 가까워서(...) 아직 잘 모르는 것도 있다. 아무튼 다 들고 올 수 있다면 OK.
아무튼 SkillData에 프로퍼티 형식으로 json의 데이터들을 정리하고, SetData로 한번에 넣어준다.
그럼 실제 사용은 어떻게 되는가?
:
☆짜잔☆
(SkillData data){SetData(data)} 복붙만 하면 된다.
그리고 스킬을 각각의 함수에 때려 넣는다.
상속받는 각 클래스의 함수는 다음과 같이 지정했다.
1. UseSkill (Character character, List <Monster> monsters) -오버라이드 필요
: 스킬을 '실행'하는 함수. '스킬 사용'시 불려오며, '단발성'으로 처리되는 효과(ex. 공격 실행. 체력회복)도 함께 작성한다.
2. ApplyEffect()
: 스킬의 효과 중 '지속 효과'를 실행하는 함수. n턴 동안 지속되는 효과는 여기에 작성된다. 지속 효과가 없는 경우 삭제한다.
3. OnEffectEnd() -오버라이드 필요
: ApplyEffect() 에서 실행된 효과를 제거하는 함수. 매 턴의 마지막, 스킬의 상태를 업데이트 하는 함수에 포함시킨다. 필요 없는 경우 공란으로 둔다. 전투 종료시에도 사용하여 player가 가진 모든 스킬을 reset시키는 역할을 한다.
2. 효과 구현
UseSkill 함수를 실행 시키면, 공통적으로 2~3개의 함수를 불러들인다.
1. 스킬이 사용 가능 상태인지 검사하는 함수형 불리언 (쿨타임이 남아있거나, 마나가 부족하면 false를 반환)을 사용하여, 조건이 맞지 않다면 실행 불가 처리.
2. Target 리스트 불러오기
- var Targets=GetTarget(monsters) , 이 경우, 전체 범위 공격이라면 target in targets를 이용해 foreach문으로 모두 동일한 처리를 해주며, 단일 공격이라면 GetTarget에서 지정한 target 하나를 불러오면 된다.(var target = targets[0])
반대로 자기자신만을 대상으로 하는 스킬이라면 GetTarget 함수를 불러올 필요 없이 바로 작성하도록 되어있다.
이를 활용하면, 이후에는 2명, 3명을 선택하여 공격하는 스킬도 만들 수 있다.
3. SkillUse(character) - 캐릭터가 스킬을 사용했고, 스킬의 대사를 출력하는 출력용 함수 (정말 대사만 있다.)
3. 그 외의 세부요소
스킬 사용 턴을 조절하기 위한 요소들도 만들었다.
현재 전투 로직은 반드시 (선공: 플레이어 후공: 적)으로 되어있다.
즉, 플레이어가 선공인 상황에서 버프형 스킬을 사용할 경우, 한 턴은 그대로 사라진다.
(2턴짜리 버프라고 생각해보자. 그나마 회피율 상승 같은 버프는 다음 턴 대상이 에너미니까 괜찮지만, 공격력 상승 같은 버프는 공격도 못하는데 1턴이 사라지게 된다.)
이를 방지하기 위해, 다음과 같은 구조를 형성했다.
//스킬의 쿨타임 감소/효과 제거 관리- 매 턴의 마지막에 확인할 것
public virtual void UpdateSkillState()
{
//WorksNow가 활성화 되어있다면, WorksNow를 종료시키고 쿨타임과 EffectDuration 감소 없음.
if (WorksNow == true) { WorksNow = false;}
else
{
if (CurrentCoolDown > 0) CurrentCoolDown--;
if (EffectDuration > 0) EffectDuration--;
if (EffectDuration == 0 && ItWorks) //효과 끝! -효과 되돌려야함
{
OnEffectEnd();
ItWorks = false;
Console.WriteLine($"{SkillOwner.Name}의 {SkillName} 효과가 해제되었습니다.");
}
}
}
매 턴의 마지막에 확인하게 될 메서드이다.
(수정할 게 있을지도 몰라서 virtual로 했는데, 그냥 void로 했어도 되었을듯;)
턴의 조절을 불리언으로 하고 있다.
불리언의 요소들은 다음과 같다.
ItWorks : 현재 효과가 적용 중인지 확인하는 요소. 누적되는 효과를 가진 스킬을 제외한 모든 스킬에 달려있다. true값인 경우 현재 스킬의 효과가 적용 중인 상태라는 뜻.
WorksNow: 이번 턴에서 해당 효과가 생겼는지 확인하는 요소. 즉, 그냥 허망하게 날아가는 한 턴을 보안하기 위한 불리언이다. true 값이라면 스킬이 해당 턴에서 사용되었다는 뜻이다.
CurrentCoolDown = 현재 남은 쿨타임. 0이되면 스킬 사용이 가능해진다. 마찬가지로 스킬을 사용한 턴에서 즉시 쿨타임이 깎이지 않도록 WorksNow를 확인한다.
EffectDuration = 효과가 지속되는 남은 턴 수. 0이 되면 효과가 종료된다. 0이되는 즉시 종료되어야 하기 때문에, if(EffectDuration >0) 다음에 오는 효과 종료 확인 조건문을 else if가 아니라 if로 설정했다.
4. 효과의 저장방법
효과 저장에는 Dictionary를 사용했다. 사실 플레이어가 1 명이기 때문에, Dictionary는 불필요하고 과하게 느껴질 수 있다.
하지만, Dictionary를 이용하면 효과가 여러개 발생해도 추가하고 빼기 쉬워지며, 플레이어블 캐릭터가 늘어나도 대응하기 좋아진다. (스킬 주인의 이름을 Key값으로 지정하면 된다.)
우선 스킬의 필드에 추가될 보너스 값과, 해당 값들을 담을 Dictionary를 만들어준다.
위 스킬은 상수값으로 효과가 지정되어있어서 필드에 즉시 선언했지만,
만약 캐릭터의 특정 요소 * 1.6 과 같은 추가 값이라면 private int Dex; 로 지정하고 넣어두면 된다.
그럼 이런 형태로 ApplyEffect에 넣으면 된다.
Dictionary에 쓰는 이유는, 이후 전투 종료 시 정확히 추가되었던 값 만큼을 빼는 것으로 원 상태로 복구하기 위함이다.
(처음에는 attack * 0.6 같은 걸 그대로 썼다. 그런데 이걸 (int)로 바꾸어 계산하고 바꾸다 보니 처음에 넣은 값과 같은 값을 적용하는지 알 수 없게 되었다.)
(과거의 다른 스킬 상태...)
defense의 0.3(30%)를 int 값으로 변환하여 bonus로 저장, 이후 else if에서 제거한다.
하지만 이건 같은 함수여서 그렇지(OnEffectEnd 함수도 없었다.),
다른 함수에 할당하려고 하면 제대로 작동하고 있는지 의심스러울 수밖에 없다. 데이터가 바뀌어도 왜 바뀌었는지 찾기도 어려운 구조.
하지만 Dictionary를 쓰는 지금은?
OnEffectEnd() 에서 변했을지도 모를 DEXbonus 같은 걸 빼지 않고 Dictionary에 있는 값을 그대로 다시 빼주면 끝난다.
(여기서는 15라는 고정값이니 상관 없지만, 통일성을 위해 동일하게 맞추었다.)
그리고 효과가 끝났으니 buffs Dicrionary에서 빼주면 된다.
여기서 해당 스킬을 사용하는 플레이어나 대상이 늘어날 경우. foreach를 이용해서 각각의 key값이 해당 Dictionary에 있는지 확인하고, 있는 애들만 버프를 빼주면 되니까 어렵지 않다.
(사실, 그래서 foreach문을 쓰려고 했다가, 여기서 플레이어는 계속 1명 뿐이고 플레이어만 스킬을 사용하므로 if문으로 고정했다.)
3. 내일의 할 일
내일은 주말이다!
오늘까지 열심히 했으니, 오늘까지 해온 일을 복기하면서 한 번 숨을 돌리고 쉬어보기로 한다.
다음주 월요일까지가 팀플이고, 그 다음에는 다시 유니티니까 힘내자.
'Unity_본캠프' 카테고리의 다른 글
[내일배움캠프 16일차] 오, 발표회. (1) | 2025.04.28 |
---|---|
[내일배움캠프 3주차] TextRPG 팀플 (1) | 2025.04.28 |
[내일배움캠프 14일차] TextRPG-이번에는 팀플이다! 4 (0) | 2025.04.24 |
[내일배움캠프 13일차] TextRPG-이번에는 팀플이다! 3 (2) | 2025.04.23 |
[내일배움캠프 12일차] TextRPG-이번에는 팀플이다! 2 (2) | 2025.04.22 |