Unity/개발연습
[Unity] Behaviour Tree Editor 제작기 - 7
민트초밥
2024. 10. 21. 11:14
Sequence Node 로직 변경
Sequence Node의 문제점을 발견했다.
예를들어 아래와 같이 3초 대기 후 타겟에게 이동하는 상황에서 예상한 결과는 이렇지만
1. 3초 대기
2. 타겟과 근접할 때까지 이동
결과는 아래와 같았다.
1. 3초 대기
2. 타겟에게 이동하지만 1프레임만 이동
3. 다시 3초 대기 후 1프레임 이동
문제는 Wait 노드의 구현 방식이었다.
일정 시간이 지난 후 elapsedTime 변수를 0으로 만들고 Success 상태로 변경하기 때문에 다음 평가 때 Running 상태가 되면서 Wait 노드를 재실행한다.
public override NodeStates Evaluate()
{
if (elapsedTime < waitTime)
{
elapsedTime += Time.deltaTime;
return NodeStates.Running;
}
else
{
elapsedTime = 0f;
return NodeStates.Success;
}
}
즉, Action Node는 자체에서 Success 상태를 변경시키지 않아야 한다.
Wait 노드에서 초기화를 시킬 수 있는 함수 추가
public override void Refresh()
{
base.Refresh();
elapsedTime = 0f;
}
public override NodeStates Evaluate()
{
if (elapsedTime < waitTime)
{
elapsedTime += Time.deltaTime;
return NodeStates.Running;
}
else
{
return NodeStates.Success;
}
}
Sequence 노드에 모든 자식 노드들이 Success인 경우 초기화 함수 실행
public override NodeStates Evaluate()
{
foreach (string nodeGuid in childNodeGuidList)
{
BehaviourNode node = tree.FindNode(nodeGuid);
if (node == null)
{
Debug.LogError($"{nameof(SelectorNode)} : Child Node Not Found");
continue;
}
switch (node.Evaluate())
{
case NodeStates.Running:
NodeState = NodeStates.Running;
return NodeState;
case NodeStates.Failure:
NodeState = NodeStates.Failure;
return NodeState;
}
}
// 모든 자식 노드들이 Success 상태인 경우 None 상태로 변경
foreach (string nodeGuid in childNodeGuidList)
{
BehaviourNode node = tree.FindNode(nodeGuid);
if (node is ActionNode actionNode)
node.Refresh();
}
NodeState = NodeStates.Success;
return NodeState;
}
반응형