목차
BT 구현 시작, 코드 리뷰 가능할까...?
오늘 구현이 급하고.. 중간에 정전이 두 번이나 발생해서 멘붕인 관계로 한 일과 내일 할 일만 간단히.
지금까지 구현된 상황은 다음과 같다.
어택 가능한 상황인지 확인 -> 공격 선택 (스킬 셔플돌려서 순차적으로 조건에 부합하는지 검사) -> 할 공격 없으면 chase모드. (현재는 테스트용으로 특정거리에서 멈추고 있음)
BT 구현 시작
드디어 BT를 구현하기 시작했다.
역시나 구현을 하면서 구조를 조금씩 건들였고, 초반에는 최최최최최종까지 붙여가며 refactor와 feat 커밋을 구분하였으나 중간부터는 구분 없이 feat 커밋할때 같이 커밋했다.
인스펙터 친화적으로 만들기
BT Node를 시각화하기 전까진, 인스펙터에서 확인을 할 수 있어야 한다.
그 생각에 무언가 많이 했는데.. 기억이 안난다. abstract을 몇군데에서 뺐던 것 같다.
ActionNode의 경우, abstract이 빠지면 new 생성자로도 생성할 수 있고,
클래스를 상속받아 생성할 수도 있기 때문에 양 쪽도 전부 만족할 수 있도록 아래와 같이 짰는데...
여전히 의심스럽다... 협업에 적합한 코드일까? 의심스러워서 생성형AI한테 코드를 제공하고 물어봤지만... AI는 믿을 수 없는 노릇.
내일 팀원들과 리뷰를 해야한다.
public class ActionNode : LeafNode
{
protected Func<NodeState> action;
/// <summary>
/// new 생성자를 통해 ActionNode 생성할때는 action을 넣어줘야합니다.
/// 자식클래스를 생성할때는 Act 오버라이드하고 action을 넣어주지 않아도 됩니다.
/// </summary>
/// <param name="action"></param>
public ActionNode(Func<NodeState> action = null)
{
if (action == null)
{
this.action = Act;
}
else
{
this.action = action;
}
}
/// <summary>
/// ActionNode 상속받는 자식 클래스에서 오버라이드
/// ActionNode 생성할 때 Func<NodeState> action 넣어주지 않으면 이 함수가 기본으로 사용됨
/// base.Act() 호출 하면 NodeState.Success 리턴이므로 주의할 것
/// </summary>
/// <returns></returns>
protected virtual NodeState Act()
{
return NodeState.Success;
}
public override NodeState Tick()
{
return action.Invoke();
}
}

아무튼 이러한 과정들을 거쳐 이미지와 같이 인스펙터에서 확인할 수 있다.
물론. nodename은 인스펙터에서 확인하는 디버그용이므로 추후 시각화를 하고 나면 삭제해야한다.
데이터 관리
// 스페셜 스킬 셀럭터 노드 자식들 생성.
SelectorNode specialSkillSelectorNode = new SelectorNode();
specialSkillSelectorNode.nodeName = "SpecialSkillSelectorNode"; //디버깅용 노드 이름 설정.
foreach (int id in monsterModel.specialSkillIds )
{
SkillSequenceNode skillNode = SkillNodeDatabase.GetSkillNode(id);
MonsterSkillModel skillData = Temp_DataBase.GetMonsterSkillById(id);
if (skillNode != null)
{
skillNode.InitializeSkillSequenceNode(monster, target, skillData);
skillNode.nodeName = "SkillNode_" + skillData.skillName; //디버깅용 노드 이름 설정.
specialSkillSelectorNode.AddChild(skillNode);
}
}
specialSkillSelectorNode.ShuffleChildren();
attackSelectorNode.AddChild(specialSkillSelectorNode);
위의 코드를 보면, 데이터베이스가 두개나 있는 걸 확인할 수 있다.
한쪽은 정말 데이터. 근데 이것도 기획테이블에서 나온 데이터를 가공한 뒤의 데이터가 될 것이다.
DataTableManager에서는 기획테이블에서 나온 날 것의 데이터를 저장하고,
Database에서는 가공 후의 데이터를 저장해야한다.
근데 여기서 끝이 아니다.
제작한 클래스를 skillId와 묶어줘야 한다.
그 선택으로 SkillNodeDatabase를 만들었다. (정말 리스트와 GetSkillSeqenceNodeById만 있는 static 클래스다)
데이터베이스들이 많아짐에 따라 혼동이 올 수 있다. (이미 왔다.)
데이터매니저를 정립하고 여기서 기획테이블과 가공한 데이터, 그리고 스킬노드데이터베이스들을 관리해줘야할 것이다.
또한, 어떤 방법이 팀원들이 다함께 관리하기 쉬울지 상의해야할 것 같다.
느낀점
전체적으로 팀원과 계속해서 상의하며 진행해야하는 부분들을 혼자서 고민하고 선택한 방법으로 진행하다보니 확신이 없는 것 같다.
그제 튜터님꼐 갔을 때도 확신을 갖고 할 수는 없다는 식으로 조언을 들었었는데... 나는 왜 이렇게 확신을 찾는 걸까.
팀원들과의 소통이 절실하고... 절실하다...ㅜㅜ 내 선택이 옳은지 적어도 틀리지는 않았다고 확인해줄 사람들이 필요해...
정전도 제발 그만와...
내일 학습 할 것은 무엇인지
아침에 일어나서 일찍 출석하고 내 코드를 스스로 리뷰해보려고 한다.
또한 오늘 마무리하고 간단히 한일을 정리하면서 훑어보다가 발견한 것들은 다음과 같다.
1.
test용으로 스킬이 아니라 Attack을 위해서 IsAttacking쓰고 있었는데,
testSkillSequence에서는 컨디션(쿨타임)체크를 하고,
UseSkill에서는 애니메이션이 끝날때까지 Running을 반환하는 방식으로 하고 있다.
이렇게 처리할 경우 IsAttacking이 필요없을 것 같다. 쓸건지 말건지? 내일 아침에 제정신으로 다시 한번 더 체크해보자.
(지금 다시 쓰다보니까 메소드 명도 BT 설계할때랑 똑같게 변경해야할 것 같다.)
2.
SkillSelector에서 셔플 지금.. 안되고 있다.
BT 생성때만 되고 있는데 선택 성공하고 공격하고 나면 그 다음에 셔플되도록 해야한다.
skillSelector 클래스를 지금처럼 new로 생성하지 말고, SelectorNode를 상속받는 SkillSelectorNode를 구현해서 그 곳에 shuffle 메서드를 추가 및 Reset 메소드에서 실행하도록 하면 될 것 같다.
(부모 객체에서 running 끝나고 success되면 호출될수있도록)
당장은 이렇고, 내일은 아마 몬스터 팀 팀원분과 코드리뷰를 하느라 오전 시간을 쏟는 게 나을 것 같다.
아니면 애니메이션을 만져보신다고 했으니 이어서 하도록 하는 것도 나쁘지 않을듯.
왜 이렇게 자신감이 없지ㅜㅜ
'부트캠프 > 본캠프' 카테고리의 다른 글
| [내일배움캠프_2025SEP16] 1차 모의면접, DataManager 및 Data 관련 정립 (0) | 2025.09.16 |
|---|---|
| [내일배움캠프_2025SEP15] 스킬 구현 시작, 레이어비트마스크 (0) | 2025.09.15 |
| [내일배움캠프_2025SEP13]리팩토링 (0) | 2025.09.13 |
| [내일배움캠프_2025SEP12] DataHandler, 상속 설계의 중요성 (0) | 2025.09.12 |
| [내일배움캠프_2025SEP11] Behavior Tree (0) | 2025.09.11 |