비헤이비어 트리를 둘러 보려고 시도하고 있으므로 테스트 코드를 스파이 킹하고 있습니다. 내가 어려움을 겪고있는 한 가지는 우선 순위가 높은 것이 나올 때 현재 실행중인 노드를 선점하는 방법입니다.
군인을위한 다음의 단순하고 가상적인 행동 트리를 고려하십시오.
진드기가 몇 개 지나갔고 근처에 적이 없었고 군인이 잔디 위에 서 있었기 때문에 Sit down 노드가 실행되도록 선택되었습니다.
이제 싯 다운 액션은 재생할 애니메이션이 있기 때문에 실행하는 데 시간이 걸리므 Running
로 상태로 돌아갑니다 . 틱 하나 또는 두 개가지나갑니다. 애니메이션은 여전히 실행 중이지만 적 근처에 있습니까? 조건 노드 트리거. 이제 Sit down 노드를 최대한 빨리 선점 하여 Attack 노드를 실행할 수 있습니다 . 이상적으로 군인은 앉아도 끝나지 않을 것입니다. 그는 단지 앉기 시작하면 애니메이션 방향을 반대로 바꿀 수 있습니다. 사실주의를 더하기 위해 애니메이션에서 요령을 지나친 경우, 앉은 다음 다시 앉게하거나 위협에 대응하기 위해 급히 넘어 질 수도 있습니다.
내가 시도한대로 이런 상황을 처리하는 방법에 대한 지침을 찾지 못했습니다. 지난 며칠 동안 내가 소비 한 모든 문헌과 비디오는이 문제와 관련이 있습니다. 내가 찾은 가장 가까운 것은 실행중인 노드를 재설정하는 개념이지만 Sit 와 같은 노드 는 "이봐 요, 아직 끝나지 않았습니다!"라고 말할 기회를주지 않습니다.
기본 클래스 에서 Preempt()
또는 Interrupt()
메소드를 정의하려고 생각했습니다 Node
. 각기 다른 노드가 자신에게 맞는 방식으로 처리 할 수 있지만이 경우에는 병사를 최대한 빨리 발로 돌려 보내려고합니다 Success
. 이 접근법은 또한 내 기지 Node
가 다른 행동과 별도로 조건 개념을 가져야 한다고 생각합니다 . 이런 식으로 엔진은 조건 만 검사 할 수 있으며, 통과하는 경우 작업 실행을 시작하기 전에 현재 실행중인 노드를 선점 할 수 있습니다. 이 차별화가 확립되지 않은 경우 엔진은 노드를 무차별 적으로 실행해야하므로 실행중인 노드를 선점하기 전에 새로운 조치를 트리거 할 수 있습니다.
참고로 아래는 현재 기본 클래스입니다. 다시 말하지만 이것은 급격한 일이므로 가능한 한 간단하게 유지하고 필요할 때만 복잡성을 추가하려고 노력했으며 이해했을 때 지금 당장 어려움을 겪고 있습니다.
public enum ExecuteResult
{
// node needs more time to run on next tick
Running,
// node completed successfully
Succeeded,
// node failed to complete
Failed
}
public abstract class Node<TAgent>
{
public abstract ExecuteResult Execute(TimeSpan elapsed, TAgent agent, Blackboard blackboard);
}
public abstract class DecoratorNode<TAgent> : Node<TAgent>
{
private readonly Node<TAgent> child;
protected DecoratorNode(Node<TAgent> child)
{
this.child = child;
}
protected Node<TAgent> Child
{
get { return this.child; }
}
}
public abstract class CompositeNode<TAgent> : Node<TAgent>
{
private readonly Node<TAgent>[] children;
protected CompositeNode(IEnumerable<Node<TAgent>> children)
{
this.children = children.ToArray();
}
protected Node<TAgent>[] Children
{
get { return this.children; }
}
}
public abstract class ConditionNode<TAgent> : Node<TAgent>
{
private readonly bool invert;
protected ConditionNode()
: this(false)
{
}
protected ConditionNode(bool invert)
{
this.invert = invert;
}
public sealed override ExecuteResult Execute(TimeSpan elapsed, TAgent agent, Blackboard blackboard)
{
var result = this.CheckCondition(agent, blackboard);
if (this.invert)
{
result = !result;
}
return result ? ExecuteResult.Succeeded : ExecuteResult.Failed;
}
protected abstract bool CheckCondition(TAgent agent, Blackboard blackboard);
}
public abstract class ActionNode<TAgent> : Node<TAgent>
{
}
누구든지 올바른 방향으로 나를 인도 할 수있는 통찰력이 있습니까? 내 생각이 올바른 방향을 따르고 있습니까, 아니면 두려워하는만큼 순진합니까?
Stop()
활성 노드를 종료하기 전에 일부 콜백 호출 )