NBBehave 한글 번역

LJM·2024년 4월 28일
0

GameDev

목록 보기
3/5

NPBehave - An event driven Behavior Tree Library for code based AIs in Unity

NPBehave의 목표는 다음과 같습니다:

  • 가볍고, 빠르고, 간단한
  • 이벤트 중심
  • 쉽게 확장 가능
  • 코드로 AI를 정의하는 프레임워크, 시각적 편집 지원 없음

NPBehave는 강력하고 유연한 코드 기반 접근 방식을 기반으로 BehaviorLibrary의 동작 트리를 정의하고 Unreal의 동작 트리의 훌륭한 개념을 일부 혼합하여 구축했습니다. 기존 비헤이비어 트리와 달리 이벤트 기반 비헤이비어 트리는 매 프레임마다 루트 노드에서 다시 트래버스할 필요가 없습니다. 현재 상태를 유지한 채 실제로 필요할 때만 계속 트래버스합니다. 따라서 성능이 향상되고 사용이 훨씬 간편해집니다.

NPBehave에는 기존 BT 의 노드 유형이 대부분 포함되어 있지만 언리얼 엔진에서 볼 수 있는 것과 유사한 노드 유형도 있습니다. 전체 목록은 노드 유형 레퍼런스를 참조하세요. 하지만 커스텀 노드 유형을 추가하는 것은 매우 쉽습니다.

비헤이비어 트리에 대해 전혀 모르신다면 이 가마수트라 문서를 통해 이론을 먼저 익히시는 것을 추천합니다.

설치

Unity 프로젝트에 NPBehave 폴더를 끌어다 놓기만 하면 됩니다. '예제' 하위 폴더에는 몇 가지 예제 씬이 포함되어 있습니다.

예제: “Hello World” 비헤이비어 트리

예제부터 시작하겠습니다:

using NPBehave;

public class HelloWorld : MonoBehaviour
{
    private Root behaviorTree;

    void Start()
    {
        behaviorTree = new Root(
            new Action(() => Debug.Log(Hello World!))
        );
        behaviorTree.Start();
    }
}

전체 샘플

이 코드를 실행하면 “Hello World”가 계속 반복해서 출력되는 것을 볼 수 있습니다. 이는 Root 노드가 트리의 마지막 노드를 우회하면 전체 트리를 다시 시작하기 때문입니다. 이를 원하지 않는다면 다음과 같이 WaitUntilStopped 노드를 추가할 수 있습니다:

// ...
behaviorTree = new root(
	new sequence(
		new Action(() => Debug.Log(Hello World!)),
		new WaitUntilStopped()
	)
);
///... 

지금까지 이 트리에는 실제로 이벤트가 구동되는 것이 없습니다. 이에 대해 자세히 알아보기 전에 먼저 블랙보드가 무엇인지 이해해야 합니다.

블랙보드

언리얼에서와 마찬가지로 NPBehave에도 블랙보드가 있습니다. 블랙보드는 AI의 '메모리'라고 생각하면 됩니다. NPBehave에서 블랙보드는 기본적으로 변화를 관찰할 수 있는 사전입니다. 블랙보드에 값을 저장하고 업데이트하기 위해 주로 Service를 사용합니다. 그리고 BlackboardCondition 또는 BlackboardQuery를 사용하여 블랙보드의 변경 사항을 관찰하고 행동 트리를 계속 탐색합니다. 다른 모든 곳에서 블랙보드의 값에 자유롭게 액세스하거나 수정할 수 있지만(Action 노드에서도 자주 액세스하게 됩니다).

루트`를 인스턴스화하면 블랙보드가 자동으로 생성되지만 다른 인스턴스에 생성자를 제공할 수도 있습니다(이는 특히 Shared Blackboards)에 유용합니다).

예시: 이벤트 기반 동작 트리

다음은 이벤트 기반 동작에 블랙보드를 사용하는 간단한 예제입니다:

/// ...
behaviorTree = new Root(
    new Service(0.5f, () => { behaviorTree.Blackboard["foo"] = !behaviorTree.Blackboard.Get<bool>("foo"); },
        new Selector(
        
            new BlackboardCondition("foo", Operator.IS_EQUAL, true, Stops.IMMEDIATE_RESTART,
                new Sequence(
                    new Action(() => Debug.Log("foo")),
                    new WaitUntilStopped()
                )
            ),

            new Sequence(
                new Action(() => Debug.Log("bar")),
                new WaitUntilStopped()
            )
        )
    )
);
behaviorTree.Start();
//...

Full sample
| More sophisticated example

이 샘플은 500밀리초마다 'foo'와 'bar'를 번갈아 인쇄합니다. Service 데코레이터 노드를 사용하여 블랙보드에서 foo 부울 값을 토글합니다. 이 플래그에 따라 브랜치가 실행될지 여부를 결정하기 위해 BlackboardCondition 데코레이터 노드를 사용합니다. BlackboardCondition은 또한 이 값에 따라 블랙보드의 변경 사항을 감시하며, Stops.IMMEDIATE_RESTART를 제공했듯이 조건이 더 이상 참이 아닐 경우 현재 실행 중인 브랜치가 중지되고 다시 참이 되면 즉시 재시작됩니다.

*람다를 사용하는 대신 실제 메서드에 서비스를 넣어야 트리를 더 읽기 쉽게 만들 수 있다는 점에 유의하세요. 더 큰 액션도 마찬가지입니다.

Stops Rules

BlackboardCondition, Condition 또는 BlackboardQuery와 같은 일부 Decorators에는 중지 규칙을 정의할 수 있는 stopsOnChange 매개변수가 있습니다. 이 매개변수를 사용하면 Decorator가 부모 Composite 내에서 실행 중인 하위 트리의 실행을 중지할 수 있습니다. 이 매개변수는 NPBehave에서 이벤트 중심성을 강화하는 주요 도구입니다.

우선순위가 낮은 노드는 부모 Composite 내의 현재 노드 다음에 정의되는 노드입니다.

가장 유용하고 일반적으로 사용되는 중지 규칙은 SELF, IMMEDIATE_RESTART 또는 LOWER_PRIORITY_IMMEDIATE_RESTART입니다.

언리얼에 익숙하다면 주의하세요. NPBehave에서 BOTHLOWER_PRIORITY 는 약간 다른 의미를 가집니다. IMMEDIATE_RESTART는 실제로 언리얼의 Both와 일치하고 LOWER_PRIORITY_IMMEDIATE_RESTART는 언리얼의 Lower Priority와 일치합니다.

다음과 같은 중지 규칙(stop rules)이 존재합니다:

  • Stops.NONE: 데코레이터가 시작될 때만 상태를 확인하고 실행 중인 노드는 절대 중지하지 않습니다.

  • Stops.SELF: 데코레이터가 시작되면 조건을 확인하고 조건이 충족되면 블랙보드에서 변경 사항을 관찰합니다. 조건이 더 이상 충족되지 않으면 스스로 중지하여 부모 컴포짓이 다음 노드를 진행할 수 있도록 합니다.

  • Stops.LOWER_PRIORITY: 데코레이터가 시작되면 조건을 확인하고 조건이 충족되지 않으면 블랙보드의 변경 사항을 관찰합니다. 조건이 충족되면 우선순위가 낮은 노드를 중지하여 부모 컴포짓이 다음 노드를 진행할 수 있도록 합니다.

  • Stops.BOTH: 데코레이터가 자체 노드와 우선순위가 낮은 노드를 모두 중지합니다.

  • Stops.LOWER_PRIORITY_IMMEDIATE_RESTART: 데코레이터가 시작되면 조건을 확인하고 조건이 충족되지 않으면 블랙보드에서 변경 사항을 관찰합니다. 조건이 충족되면 우선순위가 낮은 노드를 중지하고 부모 컴포짓에 데코레이터를 즉시 재시작 하도록 명령합니다.

  • Stops.IMMEDIATE_RESTART: 데코레이터가 시작되면 조건을 확인하고 조건이 충족되지 않으면 블랙보드에서 변경 사항을 관찰합니다. 조건이 충족되면 우선순위가 낮은 노드를 중지하고 부모 컴포짓에 데코레이터를 즉시 재시작 하도록 명령합니다. '둘 다'에서와 마찬가지로 조건이 더 이상 충족되지 않는 즉시 자체적으로 중지됩니다.

Blackboard 대안

NPBehave에서는 MonoBehaviour 내에서 동작 트리를 정의하므로 모든 것을 블랙보드에 저장할 필요가 없습니다. Stops.NONE이 아닌 다른 중지 규칙이 있는 BlackboardDecorator 또는 BlackboardQuery가 없는 경우 블랙보드에 전혀 필요하지 않을 수 있습니다. 일반 멤버 변수를 사용하는 것이 더 깔끔하고, 작성 속도가 빠르며, 성능이 더 좋은 경우가 많습니다. 이 경우 NPBehave의 이벤트 중심성을 활용하지 않는다는 뜻이지만, 그럴 필요가 없는 경우가 많습니다.

Blackboard를 사용하지 않고 stopsOnChange stops rules을 사용하려는 경우 NPBehave에는 두 가지 대체 방법이 있습니다:

  1. 일반 Condition decorator를 사용합니다. 이 데코레이터에는 선택적 stopsOnChange stops rules 매개변수가 있습니다. Stops.NONE이 아닌 다른 값을 제공하면 조건은 조건을 자주 확인하고 주어진 query 함수의 결과가 변경되면 중지 규칙에 따라 노드를 중단합니다. 이 메서드는 이벤트 기반이 아니며 매 프레임(또는 지정된 간격)마다 쿼리하므로 많이 사용하면 쿼리가 많이 발생할 수 있다는 점에 유의하세요. 그러나 간단한 경우에는 이 방법으로도 충분하며 Blackboard-Key, ServiceBlackboardCondition을 조합하는 것보다 훨씬 간단합니다.
  2. 나만의 이벤트 기반 Decorator를 구축합니다. 실제로는 매우 간단합니다. ObservingDecorator에서 확장하고 isConditionMet(), StartObserving()StopObserving() 메서드를 재정의하기만 하면 됩니다.

노드 실행 결과

NPBehave에서 노드는 succeed하거나 fail할 수 있습니다. 기존 behavior trees와 달리 노드가 실행되는 동안에는 결과가 없습니다. 대신 노드가 완료되면 노드 자체적으로 부모 노드에 알립니다. 이는 자신만의 노드 유형을 만들 때 염두에 두어야 할 중요한 사항입니다.

노드 유형

NPBehave에는 네 가지 노드 유형이 있습니다:

  • 루트 노드: 루트는 하나의 자식을 가지며 전체 동작 트리를 시작하거나 중지하는 데 사용됩니다.

  • 복합 노드: 여러 개의 자식을 가지고 있으며 자식 중 어떤 노드가 실행되는지 제어하는 데 사용됩니다.

  • 데코레이터 노드: 이 노드는 항상 정확히 하나의 자식을 가지며 자식의 결과를 수정하거나 자식을 실행하는 동안 다른 작업을 수행하는 데 사용됩니다(예: 블랙보드를 업데이트하는 서비스).

  • 작업 노드: 실제 작업을 수행하는 트리의 리프입니다. 사용자 정의 클래스를 만들 가능성이 가장 높은 노드입니다. 람다나 함수와 함께 Action을 사용할 수 있습니다 - 더 복잡한 작업의 경우 Task의 새로운 하위 클래스를 만드는 것이 더 나은 옵션인 경우가 많습니다. 그렇게 할 경우 the golden rules을 반드시 읽어보세요.

Stopping the Tree

몬스터가 죽거나 게임 오브젝트를 파괴한 경우, 항상 트리를 멈춰야 합니다. 스크립트에 다음과 같은 내용을 넣을 수 있습니다:

    // ...
    public void OnDestroy()
    {
        StopBehaviorTree();
    }

    public void StopBehaviorTree()
    {
        if ( behaviorTree != null && behaviorTree.CurrentState == Node.State.ACTIVE )
        {
            behaviorTree.Stop();
        }
    }
    // ...

디버거

디버거` 컴포넌트를 사용하여 인스펙터에서 런타임에 동작 트리를 디버깅할 수 있습니다.

NPBehave Debugger

Check out the sample

공유 블랙보드

여러 AI 인스턴스에서 블랙보드를 공유할 수 있는 옵션이 있습니다. 이 옵션은 일종의 스웜 동작을 구현하려는 경우에 유용할 수 있습니다. 또한 블랙보드 계층 구조를 생성하여 공유된 블랙보드와 공유되지 않은 블랙보드를 결합할 수 있습니다.

UnityContext.GetSharedBlackboard(name)를 사용하여 어디서나 공유 블랙보드 인스턴스에 액세스할 수 있습니다.

Check out the sample

라이브러리 확장하기

사용자 지정 노드 유형을 생성하는 방법은 기존 노드 구현을 참조하되, 생성하기 전에 최소한 다음 황금률(golden rules)을 읽어 보시기 바랍니다.

황금률

  1. DoStop()을 호출할 때마다 Stopped(result) 를 호출해야 합니다. 이것은 매우 중요합니다! NPBehave는 실행 중인 브랜치를 매번 즉시 취소할 수 있어야 하므로, DoStop() 내에서 Stopped()가 호출되는지 확인해야 합니다. 이는 또한 모든 자식 노드도 Stopped()를 호출한다는 것을 의미하므로 안정적인 데코레이터나 복합 노드를 작성하기가 정말 쉬워집니다: DoStop() 내에서 활성 자식 노드에 Stop()을 호출하기만 하면, 자식 노드에서 차례로 ChildStopped()을 호출한 다음 마지막으로 Stopped() 호출을 넣으면 됩니다. 참고를 위해 기존 구현을 살펴보세요.
  2. Stopped()는 마지막 호출 이므로, Stopped 호출 이후에는 상태를 수정하거나 다른 호출을 하지 마세요. Stopped는 즉시 다른 노드에서 트리를 계속 탐색하기 때문에 이를 고려하지 않으면 동작 트리의 상태가 완전히 엉망이 될 수 있기 때문입니다.
  3. 등록된 모든 시계 또는 블랙보드 관찰자는 결국 제거해야 합니다. 대부분의 경우 Stopped()를 호출하기 직전에 콜백을 등록 취소하지만 예외가 있을 수 있습니다. 예를 들어 BlackboardCondition은 부모 컴포지트가 중지될 때까지 관찰자를 유지하므로 노드 자체가 활성화되어 있지 않아도 블랙보드 값 변경에 반응할 수 있어야 합니다.

작업 구현하기

Task클래스에서 확장한 태스크의 경우DoStart()DoStop() 메서드를 재정의합니다. DoStart()에서 로직을 시작하고 완료되면 적절한 결과와 함께 Stopped(bool result)를 호출합니다. 다른 노드에 의해 노드가 취소될 수 있으므로 DoStop()을 구현하고 적절한 정리를 수행한 후 바로 뒤에 Stopped(bool result)를 호출해야 합니다.

비교적 간단한 예제는 Wait Task의 소스를 참고하세요.

황금률 섹션에서 이미 언급했듯이, NPBehave에서는 노드가 중지된 후 항상 Stopped(bool result)를 호출해야 합니다. 따라서 현재 여러 프레임에 걸쳐 취소 연산을 보류하는 것은 지원되지 않으며 예측할 수 없는 동작이 발생할 수 있습니다.

관찰 데코레이터 구현하기

데코레이터를 작성하는 것은 태스크보다 훨씬 더 복잡합니다. 하지만 편의를 위해 특별한 베이스 클래스가 존재합니다. 바로 ObservingDecorator 관찰 데코레이터 입니다. 이 클래스는 선택적으로 stopsOnChange stops rules을 사용하는 "conditional" Decorators를 쉽게 구현하는 데 사용할 수 있습니다.

ObservingDecorator를 확장하고 bool IsConditionMet() 메서드를 재정의하기만 하면 됩니다. 만약 Stops-Rules를 지원하려면 StartObserving()StopObserving()도 구현해야 합니다. 간단한 예제는 Condition Decorator의 소스를 확인하세요.

제네릭 데코레이터 구현하기

일반 데코레이터의 경우 Decorator 클래스에서 확장하여 DoStart(), DoStop()DoChildStopped(Node child, bool result) 메서드를 재정의합니다.

데코레이터 노드는 Decoratee 프로퍼티에 접근하여 Start() 또는 Stop()을 호출하여 시작하거나 중지할 수 있습니다.

데코레이터가 DoStop() 호출을 받으면 그에 따라 Decoratee를 중지해야 하며, 이 경우 Stopped(bool result)를 즉시 호출하지 않습니다. 대신 DoChildStopped(Node child, bool result) 메서드에서 이를 수행합니다. DoChildStopped(Node child, bool result)가 반드시 데코레이터가 데코티어를 중지했다는 것을 의미하지는 않으며, 데코티어가 스스로 중지할 수도 있으므로 이 경우 데코티어를 즉시 중지할 필요가 없습니다(쿨다운 등을 구현하려는 경우 유용할 수 있습니다). 데코레이터가 중지되었는지 확인하려면 해당 데코레이터의 IsStopRequested 프로퍼티를 쿼리하면 됩니다.

아주 기본적인 구현은 Failer Node, 조금 더 복잡한 구현은 Repeater Node의 소스를 확인하세요.

또한 데코레이터가 비활성 상태일 때도 호출할 수 있는 DoParentCompositeStopped() 메서드를 구현할 수도 있습니다. 이 메서드는 데코레이터가 중지된 후에도 활성 상태로 유지한 리스너에 대해 추가 정리 작업을 수행하려는 경우에 유용합니다. 예제는 ObservingDecorator를 확인하세요.

컴포짓 구현하기

컴포짓 노드는 라이브러리에 대한 깊은 이해가 필요하며 일반적으로 새로운 노드를 구현할 필요는 없습니다. 새로운 컴포짓이 꼭 필요한 경우 GitHub 프로젝트에 티켓을 생성하거나 문의하기를 통해 문의해 주시면 최선을 다해 도와드리겠습니다.

노드 상태

대부분 액세스할 필요는 없지만 알아두는 것이 좋습니다:

  • ACTIVE: 노드가 시작되었지만 아직 중지되지 않은 상태입니다.
  • STOP_REQUESTED: 노드가 현재 중지 중이지만 아직 부모에게 알리기 위해 Stopped()를 호출하지 않았습니다.
  • INACTIVE: 노드가 중지되었습니다.

현재 상태는 CurrentState 프로퍼티로 검색할 수 있습니다.

시계

노드의 시계를 사용하여 타이머를 등록하거나 매 프레임마다 알림을 받을 수 있습니다. 시계에 접근하려면 RootNode.Clock을 사용합니다. 시계에 타이머를 등록하는 방법에 대한 예제는 대기 작업을 참조하세요.

기본적으로 behavior tree 는 UnityContext에 의해 제공된 글로벌 시계를 사용합니다. 이 시계는 매 프레임마다 업데이트됩니다.
더 많은 제어를 원하는 경우가 있을 수 있습니다. 예를 들어 AI 그룹에 대한 업데이트를 스로틀하거나 일시 중지하고 싶을 수 있습니다. 이러한 이유로 '루트' 노드와 '블랙보드'에 자체 제어 클럭 인스턴스를 제공하면 동작 트리가 업데이트되는 시기를 정확하게 제어할 수 있습니다. 시계 스로틀링 예시](https://github.com/meniku/NPBehave/blob/master/Examples/Scripts/NPBehaveExampleClockThrottling.cs)를 확인하세요.

노드 유형 참조

루트

  • Root(Node mainNode): 실패 상태와 상관없이 주어진 mainNode를 끝없이 실행합니다.
  • Root(Blackboard blackboard, Node mainNode): 인스턴스화 대신 주어진 blackboard를 사용합니다; 실패 상태와 상관없이 주어진 mainNode를 끝없이 실행합니다.
  • Root(블랙보드 블랙보드, 시계 시계, 노드 메인노드): 인스턴스화하는 대신 주어진 blackboard를 사용; UnityContext의 전역 시계를 사용하는 대신 주어진 clock을 사용; 성공 상태에 관계없이 주어진 mainNode를 끝없이 실행합니다.

컴포짓 노드

셀렉터

  • Selector(params Node[] children): 하나의 노드가 성공할 때까지 자식들을 순차적으로 실행하여 성공시킵니다(자식 중 하나가 성공하면 성공).

시퀀스

  • Sequence(params Node[] children): 하나의 자식이 실패할 때까지 순차적으로 자식을 실행하고 실패합니다(자식 중 실패한 것이 없으면 성공).

Parallel

  • 병렬(정책 성공정책, 정책 실패정책, 매개변수 Node[] 아이들): 자식들을 병렬로 실행합니다. failurePolocityPolociy.ONE인 경우, 자식 중 하나가 실패하는 즉시 병렬이 중지됩니다(실패한 결과와 함께). successPolicyPolicy.ONE인 경우, 자식 중 하나가 실패하면 병렬이 중지됩니다(성공 결과와 함께). Policy.ONE으로 인해 병렬이 중지되지 않으면 모든 자식이 완료될 때까지 실행되며, 모든 자식이 성공하거나 실패하면 성공합니다.

RandomSelector

  • RandomSelector(params Node[] children): 한 개가 성공할 때까지 자식들을 무작위 순서로 실행하여 성공합니다(자식 중 하나가 성공하면 성공). 중단 규칙의 경우 원래 순서가 우선순위를 정의한다는 점에 유의하세요.

RandomSelector

  • RandomSequence(params Node[] children): 한 개가 실패할 때까지 자식을 무작위 순서로 실행하고 실패하면 성공합니다(자식 중 실패한 것이 없으면 성공). 중단 규칙의 경우 원래 순서가 우선순위를 정의한다는 점에 유의하세요.

태스크 노드

Action

  • Action(System.Action action): 실행 후 잊어버리기 액션(항상 즉시 성공적으로 완료)
  • Action(System.Func<bool> singleFrameFunc): 성공 또는 실패할 수 있는 액션(실패하면 false 반환)
  • Action(Func<bool, Result> multiframeFunc): 여러 프레임에 걸쳐 틱할 수 있는 액션(액션이 아직 준비되지 않은 경우 Result.BLOCKED, 액션이 진행 중이면 Result.PROGRESS, 액션이 실패하면 Result.SUCCESS 또는 Result.FAILED를 반환).
  • Action(Func<Request, Result> multiframeFunc2): 위와 비슷하지만, Request.START는 액션의 첫 번째 틱이거나 마지막 틱에 Result.BLOCKED를 반환했음을 의미하며, Result.UPDATE는 마지막으로 Result.PROGRESS를 반환했다는 의미, Result.CANCEL은 액션을 취소하고 Result.SUCCESS 또는 Result.FAILED를 반환해야 한다는 의미의 상태 정보를 알려줍니다.
  • NavMoveTo(NavMeshAgent agent, string blackboardKey, float tolerance = 1.0f, bool stopOnTolerance = false, float updateFrequency = 0.1f, float updateVariance = 0.025f): 주어진 blackboardKey에 저장된 변환이나 벡터로 NavMeshAgent agent를 이동시킵니다. '허용 오차' 거리를 허용하고 선택적으로 허용 오차 범위에서 한 번 멈춥니다(stopOnTolerance). 업데이트 빈도`는 목표 위치가 업데이트되는 빈도와 작업이 완료되었는지 여부를 확인하는 빈도를 제어합니다.

Wait

  • Wait(float seconds): 0.05 * 초의 무작위 분산으로 주어진 초 동안 기다립니다.
  • Wait(float seconds, float randomVariance): 주어진 임의의 분산으로 주어진 초 동안 기다립니다.
  • Wait(string blackboardKey, float randomVariance = 0f): 주어진 blackboardKey에 float로 설정된 초 동안 기다립니다.
  • Wait(System.Func<float> 함수, float randomVariance = 0f): 주어진 람다 함수의 결과를 기다립니다.

WaitUntilStopped

  • WaitUntilStopped(bool sucessWhenStopped = false): 다른 노드에 의해 중지될 때까지 기다립니다. 이 함수는 종종 선택자의 끝에 파킹되어 앞의 형제자매인 BlackboardCondition, BlackboardQuery 또는 Condition이 활성화되기를 기다리는 데 사용됩니다.

데코레이터 노드 ###

BlackboardCondition

  • BlackboardCondition(string key, Operator operator, object value, Stops stopsOnChange, Node decoratee): 블랙보드의 keyop / value 조건과 일치할 때만 decoratee 노드를 실행합니다. stopsOnChange가 NONE이 아닌 경우 노드는 Blackboard의 변경 사항을 관찰하고 stopsOnChange stops rules에 따라 실행 중인 노드의 실행을 중지합니다.
  • BlackboardCondition(string key, Operator operator, Stops stopsOnChange, Node decoratee) : Blackboard의 keyop 조건과 일치하는 경우에만 decoratee 노드를 실행합니다(예: 피연산자 연산자 중 하나가 IS_SET만 확인하는 경우). stopsOnChange가 NONE이 아닌 경우 노드는 Blackboard에서 변경 사항을 관찰하고 stopsOnChange stops rules에 따라 실행 중인 노드의 실행을 중지합니다.

BlackboardQuery

  • BlackboardQuery(string[] keys, Stops stopsOnChange, System.Func<bool> query, Node decoratee): BlackboardCondition은 하나의 키만 확인할 수 있는 반면, 이 함수는 여러 개의 블랙보드 키를 관찰하고 값 중 하나가 변경되는 즉시 주어진 query 함수를 평가하여 블랙보드에서 임의의 쿼리를 수행할 수 있도록 합니다. 이 노드는 stopsOnChange stops rules에 따라 노드 실행을 중지합니다.

Condition

  • Condition(Func<bool> condition, Node decoratee): 주어진 condition이 참을 반환하면 decoratee 노드를 실행합니다.
  • Condition(Func<bool> condition, Stops stopsOnChange, Node decoratee): 주어진 condition이 참을 반환하면 decoratee 노드를 실행합니다. 매 프레임마다 조건을 재평가하고 stopsOnChange stops rules에 따라 노드 실행을 중지합니다.
  • Condition(Func<bool> condition, Stops stopsOnChange, float checkInterval, float randomVariance, Node decoratee): 주어진 조건이 참을 반환하면 decoratee 노드를 실행합니다. 주어진 checkIntervalrandomVariance에서 조건을 재평가하고 stopsOnChange stops rules에 따라 노드 실행을 중지합니다.

쿨다운

  • Cooldown(float cooldownTime, Node decoratee): decoratee를 즉시 실행하되, 마지막 실행이 적어도 cooldownTime을 지나지 않은 경우에만 실행합니다.

  • Cooldown(float cooldownTime, float randomVariation, Node decoratee): decoratee를 즉시 실행하되, 마지막 실행이 적어도 randomVariation으로 cooldownTime을 지나지 않은 경우에만 실행합니다.

  • Cooldown(float cooldownTime, bool startAfterDecoratee, bool resetOnFailiure, Node decoratee): decoratee를 즉시 실행하되, 마지막 실행이 적어도 randomVariation으로 cooldownTime을 지나지 않은 경우에만 실행합니다. resetOnFailure가 참이면, 장식된 노드가 실패하면 쿨다운이 초기화됩니다.

  • Cooldown(float cooldownTime, float randomVariation, bool startAfterDecoratee, bool resetOnFailiure, Node decoratee) 마지막 실행이 적어도 randomVariation으로 cooldownTime이 지나지 않은 경우에만 즉시 decoratee를 실행합니다. startAfterDecoratee가 참이면, 쿨다운 타이머는 장식이 시작될 때가 아니라 완료된 후에 시작됩니다. resetOnFailure가 참이면 장식 노드가 실패하면 쿨다운이 초기화됩니다.

Failer

  • Failer(Node decoratee): decoratee의 결과와 상관없이 항상 실패합니다.

Inverter

  • Inverter(Node decoratee): decoratee가 성공하면 인버터가 실패하고, decoratee가 실패하면 인버터가 성공합니다.

관찰자

  • Observer(Action onStart, Action<bool> onStop, Node decoratee): decoratee가 시작되면 주어진 onStart 람다를 실행하고, decoratee가 완료되면 onStop(bool result) 람다를 실행합니다. 이는 decoratee의 실행에 직접 간섭하지 않기 때문에 특별한 종류의 Service와 비슷합니다.

Random

  • Random(float probability, Node decoratee): 0과 1 사이의 주어진 probability 확률로 decoratee를 실행합니다.

Repeater

  • Repeater(Node decoratee): 실패하지 않는 한, 주어진 decoratee를 무한히 반복합니다.
  • Repeater(int loopCount, Node decoratee): 주어진 decorateeloopCount만큼 실행합니다(0은 decoratee 장식자가 실행되지 않음을 의미). decoratee가 멈추면 루핑이 중단되고 리피터는 실패합니다. decoratee의 모든 실행이 성공하면 리피터는 성공합니다.

서비스

  • Service(Action service, Node decoratee): 주어진 서비스 함수를 실행하고 decoratee를 시작한 다음 매 틱마다 서비스를 실행합니다.
  • Service(float interval, Action service, Node decoratee): 주어진 service 함수를 실행하고, decoratee를 시작한 다음 주어진 intervalservice를 실행합니다.
  • Service(float interval, float randomVariation, Action service, Node decoratee): 주어진 service 함수를 실행하고, decoratee를 시작한 다음 randomVariation으로 주어진 interval에서 service를 실행합니다.

Succeeder

  • Succeeder(Node decoratee): decoratee의 성공 여부에 관계없이 항상 성공합니다.

TimeMax

  • TimeMax(float limit, bool waitForChildButFailOnLimitReached, Node decoratee): 주어진 decoratee를 실행합니다. 만약 decorateelimit 내에서 끝나지 않으면 실행은 실패합니다. waitForChildButFailOnLimitReached`가 참이면 데코레이터가 완료될 때까지 기다리지만 여전히 실패합니다.

  • TimeMax(float limit, float randomVariation, bool waitForChildButFailOnLimitReached, Node decoratee): 주어진 decoratee를 실행합니다. 만약 decorateelimitrandomVariation 내에서 끝나지 않으면 실행이 실패합니다. waitForChildButFailOnLimitReached`가 참이면 데코레이터가 완료될 때까지 기다리지만 여전히 실패합니다.

TimeMin

  • TimeMin(float limit, Node decoratee): 주어진 decoratee를 실행합니다.limit 시간에 도달하기 전에 Decoratee가 성공적으로 완료되면 데코레이터는 제한에 도달할 때까지 기다린 다음 Decoratee의 결과를 가지고 실행을 중지합니다. 만약 '제한' 시간에 도달하기 전에 decoratee가 실패하면 데코레이터는 즉시 중지됩니다.
  • TimeMin(float limit, bool waitOnFailure, Node decoratee): 주어진 decoratee를 실행합니다. 만약 decorateelimit 시간에 도달하기 전에 성공하면, 데코레이터는 한계에 도달할 때까지 기다렸다가 Decoratee의 결과를 가지고 실행을 중지합니다. waitOnFailure가 참이면 decoratee가 실패할 때도 데코레이터가 대기합니다.
  • TimeMin(float limit, float randomVariation, bool waitOnFailure, Node decoratee): 주어진 decoratee를 실행합니다. 만약 decorateerandomVariationlimit 시간에 도달하기 전에 성공하면, 데코레이터는 한계에 도달할 때까지 기다렸다가 Decoratee의 결과를 가지고 실행을 중지합니다. waitOnFailure가 참이면, decoratee`는 decoratee가 실패할 때에도 대기합니다.

WaitForCondition

  • WaitForCondition(Func<bool> condition, Node decoratee): condition이 참이 될 때까지 decoratee 노드의 실행을 지연하여 매 프레임마다 확인합니다.
  • WaitForCondition(Func<bool> condition, float checkInterval, float randomVariance, Node decoratee): condition이 참이 될 때까지 decoratee 노드의 실행을 지연하여 주어진 checkIntervalrandomVariance로 확인합니다.

비디오 튜토리얼

연락처

NPBehave was created and is maintained by Nils Kübler (E-Mail: das@nilspferd.net, Skype: disruption@web.de)

Contributors

Games using NPBehave

  • Ace Of Traze Mobile

  • NPBehave를 사용하여 게임을 개발했거나 개발 중인 게임이라면 이 목록에 올려주시면 기쁩니다. 저에게 연락](#contact)을 통해 게임 아이터를 제출하거나 깃허브 페이지*에서 풀 리퀘스트를 생성하여 제출할 수 있습니다.

profile
게임개발자 백엔드개발자

0개의 댓글