유틸리티 이론
소개
Bot SDK의 유틸리티 이론은 실험 버전에 여전히 존재하며, 곧 출시가 될 수 있음을 의미하며, 향후 버전에서는 API와 성능이 향상되어야 한다는 것을 의미합니다.
개요
유틸리티 이론 AI는 수학적 모델링에 기반한 강력한 의사결정을 위한 아키텍처를 제공함으로써 작동합니다. 사용자 고유의 UT 에이전트를 작성할 때 응답 커브를 지속적으로 작성하고 조정해야 합니다. 응답 커브는 유틸리티의 AnimationCurves를 정의에 사용합니다.
모든 응답 커브는 사용자 고유의 게임 로직에 의해 정의된 입력 값을 수신합니다. 이 값을 스코어라고 합니다. 이 프로세스를 수행한 후 UT 에이전트는 체크 표시(유틸리티 이론)에 더 유용한 가능한 선택 항목이 무엇인지 파악하고 그에 따라 작동하기 시작합니다.
이에 비해 유틸리티 이론은 유한 상태 머신 및 행동 트리와 많은 차이가 있으며, 사용자가 FSM의 전환과 BT의 링크와 같이 매우 "리기드" 관계를 만들어야 하는 것이 아니기 때문에 AI 기법이 얼마나 몰입적인 행동을 만들 수 있는지에 대해 이야기할 때 목표 지향적 행동 계획과 더 유사합니다.
UTAI의 가장 큰 장점 중 하나는 응답 커브를 사용하여 매우 유연한 의사결정 공간을 정의할 수 있다는 것입니다. 예를 들면 다음과 같습니다.
- HFSM의 결정으로 거리를 체크한다는 가정: 적과의 거리가 5보다 작을 경우 요원은 도망쳐야 합니다. 이렇게 하면 의사결정이 한 극단에서 다른 극단("도망 치지 않음"에서 "도망 침")으로 이어지는 "이진 임계값"인 "보이지 않는 벽"이 만들어집니다.
- UT의 반응 커브를 사용하여 커브 자체의 본체를 통해 의사결정을 부드럽게 할 수 있습니다. 최대 효용 값이 5인 선형 곡선일 수 있습니다. 즉, 거리 값이 5로 갈수록 도망치는 대안이 선형적으로 더 중요하게 됩니다. 또는 기하급수적으로 커져서 더 빨리 쓸모가 있는 도망을 선택하게 되는 곡선일 수도 있습니다.
새로운 유틸리티 이론 AI 생성
편집기의 상단 바에서, (+) 버튼을 클릭하고 유틸리티 이론 옵션을 선택합니다.
BT 파일을 저장하라고 알려줄 것 입니다. 원하는 곳에 파일을 저장합니다. **비쥬얼 편집기**에서 작업한 내용인 생성된 데이터 에셋을 저장하는 곳 입니다.노트: 이제 선택한 이름은 비쥬얼 편집기에서 수행한 작업을 컴파일할 때 추가로 생성된 다른 데이터 에셋의 이름입니다.
Quantum 시뮬레이션에서 실제로 봇을 구동하는 데 사용되는 데이터 에셋이므로 이미 제안된 이름을 선택할 수 있습니다.
파일을 저장할 때, 작업 시작을 하게되는 메인 봇 SDK 창은 Consideration Node인 단일 노드가 생성될 것 입니다.
Consideration Node
이것은 UT 에이전트에 중요한 모든 데이터가 포함된 기본 노드 유형입니다.
Consideration 내에서 특정 고려 사항이 분석하는 반응 커브를 정의할 수 있습니다. 그런 다음 이러한 커브는 0..n 점수 값에서 비롯됩니다. 점수 값은 함께 곱해지며, 그 결과는 이른바 "고려사항을 실행하는 유틸리티"입니다.
먼저, 모든 고려 사항이 평가됩니다. 즉, 입력이 커브에 입력되어 결과적으로 점수를 얻습니다. 그런 다음 해당 프레임에서 실행할 항목으로 가장 높은 점수를 가진 고려 사항이 선택됩니다.
따라서 사용자는 자주 평가되는 고려 노드를 많이 만들고, 이러한 노드를 실행하는 것이 에이전트를 실행에 옮기게 됩니다.
고려 사항 필드를 하나씩 분석하겠습니다.
## 기본 값기본 스코어 (FP): 반응 커브의 결과는 기준 스코어로 요약됩니다. 이를 통해 주어진 고려사항에 대해 고정된 효용 값을 부여할 수 있습니다.
쿨다운 (FP): 고려가 선택되고 실행될 때, 쿨다운은 가능한 선택에서 고려가 폐기되는 시간(초)을 정의합니다.
모멘텀 양 (Int): 고려 사항을 선택하면 모멘텀이 이 필드에 정의된 값으로 순위를 높입니다. 이 옵션을 사용하여 더 많은 프레임에 대해 실행할 고려 사항을 정의하면 절대 유틸리티 값이 증가합니다. 자세한 내용은 아래 순위 항목을 참조하십시오.
모멘텀 감소 (Int): 고려 사항이 모멘텀에 있는 경우(모멘텀으로 인해 순위가 상승한 경우), 이 필드에 정의된 양만큼 매초마다 순위 값이 감소합니다. 모멘텀을 얼마나 빨리 끝낼지 표현하는 데 사용합니다.
이러한 기본값을 반드시 사용해야 하는 것은 아니지만 일부 추가 기능을 제공하는 것은 매우 유용할 수 있습니다.
액션
이 노드는 사용자가 액터를 구동하기 위해 게임 상태 변경을 수행할 수 있는 노드 유형입니다. A 지점에서 B 지점으로 액터 이동, 공격, 스캔 등 모든 작업이 액션 내에서 수행될 수 있습니다.
UT의 액션은 HFSM 및 GOAP에서 사용되는 액션과 동일합니다. 그렇기 때문에 여기을 클릭하여 접근할 수 있는 공유 문서가 있습니다.
고려 사항의 작업을 편집하려면 작업 영역을 두 번 클릭하십시오. 여기서 다음 순간 동안 액션을 연결할 수 있습니다.
- On Enter: 고려사항이 가장 유용하게 선택되고 실행되기 시작할 때 실행됩니다.
- On Update: 고려사항이 여전히 가장 유용한 것으로 선택되는 동안 모든 프레임에서 실행됩니다.
- On Exit: 이전 프레임에서 고려사항이 선택되었을 때 실행되었지만, 현재 프레임에서는 다시 선택되지 않았습니다.
순위
고려사항을 선택하는 방법에는 크게 두 가지가 있습니다. 다음과 같습니다.
- 절대적 유틸리티: 순위 값이 가장 높은 고려 사항은 낮은 순위 값보다 절대적인 선호도를 가지며, 이는 점수를 계산할 때 낮은 고려 사항이 완전히 무시됨을 의미합니다.
- 상대적 유틸리티: 이것은 이미 설명된 것으로, 반응 커브에서 평가한 점수 자체입니다.
순위 값은 정수형으로 계산됩니다. 예를 들면, 5가지 고려 사항(A, B, C, D 및 E)이며 순위 값이 다음과 같다고 가정합니다.
- A = 0;
- B = 1;
- C = 1;
- D = 2;
- E = 2.
즉, 이 프레임에서 고려 사항 D와 E는 절대적인 선호도를 가지며 반응 커브를 평가하고 둘 중 하나를 선택할 수 있도록 비교됩니다. 고려 사항 A, B, C는 무시됩니다.
순위 값을 변경하는 방법에는 크게 두 가지가 있으며, 항상 런타임에 정의되며 모든 프레임에서 변경할 수 있습니다. 이 동적 순위 값은 사용자가 자신의 게임에 맞는 순위 로직을 미리 정의하여 필요에 따라 고려 사항 하위 집합을 선호할 수 있도록 하는 데 유용합니다.
예를 들어, 저격수가 싸움을 걸거나 치료하기 위해 달려갈 수 있는 게임을 가정해 보겠습니다. 각 가능성의 유형별로 여러 가지 고려 사항이 있을 수 있습니다. 더 중요한 항목을 필터링하려면 순위 값을 높여 UT 에이전트에 표시하는 것이 유용할 수 있습니다.
순위 값을 정의하는 방법에는 두 가지가 있습니다.
나만의 순위 로직을 정의: quantum 솔루션에서 정수 값을 반환하는 일부 로직을 구현하기 위한 AIFunctionInt
클래스를 상속할 수 있습니다. 코드는 다음과 같습니다.
C#
namespace Quantum
{
[System.Serializable]
public unsafe class SampleRank : AIFunctionInt
{
public override int Execute(Frame frame, EntityRef entity = default)
{
// Add here any logic to calculate the desired Rank
return 0;
}
}
}
예를 들어 에이전트가 현재 위험한 상태인지, 가까운 적이 있는지, 아니면 LoS가 있는지를 식별하기 위해 게임 상태/블랙보드 값을 읽는 IsDangerRank
가 있을 수 있습니다. 위험이 감지될 경우 Rank 값 10
을 반환합니다. 즉, 이러한 순위를 사용할 경우 고려 사항이 매우 높은 절대 우선순위를 갖게 됩니다. 위험이 없으면 0
만 반환하면 됩니다.
Quantum 코드가 컴파일되면 콘텍스트 메뉴에서 기능 노드를 사용할 수 있습니다. 순위 노드에 접근하려면 고려 노드의 순위 영역을 두 번 클릭합니다.
또한 아래 항목에서 설명하는 모멘텀의 개념에 따라 순위 값을 변경할 수도 있습니다.
모멘텀
고려 사항의 기준 값을 사용하면 모멘텀을 지정할 수 있으며, 이 모멘텀을 선택하면 고려 사항 순위가 자동으로 상승합니다(On Enter 로직과 유사).
모멘텀의 목적은 에이전트가 너무 자주 마음을 바꾸는 것을 방지하기 위한 것입니다. 고려 사항이 지속적으로 재평가되기 때문에 에이전트가 일부 작업(예: 대상 추적)을 시작하고 다른 작업(예: 기지 보호로 돌아가기)으로 너무 빨리 전환하기 때문에 에이전트가 아무것도 끝내지 못할 수 있습니다.
그런 다음 모멘텀을 사용하여 고려의 순위가 증가하도록 지정할 수 있으며, 이를 커밋이라고 합니다. 운동량에 의해 생성된 순위 값은 동적으로 계산된 값보다 우선순위가 높습니다.
이제 모멘텀을 만들었으니 언제 다시 설정되나요? 다시 0으로 줄이는 방법에는 크게 두 가지가 있습니다.
Momentum Decay
라는 기본값을 사용하여 모멘텀의 순위를 2등까지 낮추는 데 사용할 값을 지정할 수 있습니다. 따라서 모멘텀 값을 설정하는 방법에 따라 1초 또는 몇 초의 작업만 소요됩니다. 당신에게 달렸습니다.- Commitment 체커 유형을 사용하여 모멘텀의 순위를 취소할 수도 있습니다. 모멘텀을 취소해야 할 때 지정할 수 있는 부울을 반환합니다. 커밋 체커를 만들려면
AIFuncionBool
에서 상속하고Execute
메서드를 구현하세요. 값FALSE
를 반환하면 모멘텀을 취소해야 함을 의미합니다.
C#
namespace Quantum
{
[System.Serializable]
public unsafe class SampleCommitment : AIFuncionBool
{
public override bool Execute(Frame frame, EntityRef entity = default)
{
// Implement your checking logic here
return false;
}
}
}
Quantum 코드가 컴파일되면 상황에 맞는 메뉴에서 기능 노드를 사용할 수 있습니다. 커밋 노드에 액세스하려면 커밋 영역을 두 번 클릭합니다.
어떤 조건이 충족될 때까지 오랫동안 높은 순위 값을 유지하는 것이 좋습니다. 예를 들어, 다른 캐릭터를 따르는 에이전트가 있는 경우 캐릭터가 다음 캐릭터로 시작되면 큰 순위 값을 갖도록 하고, 값이 0을 Momentum Decay로 설정하여 높게 유지되도록 한 다음, 에이전트가 여전히 목표에 도달할 수 있는지 확인하는 커밋(커밋)을 추가할 수 있습니다(단순 거리 검사일 수 있습니다. 대상이 너무 멀면 False
를 반환하면 고려 순위가 다시 0이 되어 에이전트에 다른 무언가가 더 유용해질 가능성이 높아집니다.
그렇다고 해서 두 가지 기법을 모두 사용해야 하거나 독점적으로 사용해야 하는 것은 아닙니다. 고려사항에 모멘텀을 추가하고 자연스러운 모멘텀 디케이 그리고 커밋 체커를 둘 다 사용할 수 있습니다. 하기 나름입니다.
응답 커브
이것이 이 AI 기술의 핵심입니다. 이 모든 결정은 커브 정의, 점수 매기기, 곱하기 및 결과를 결합하여 해당 프레임에서 더 유용한 것을 얻는 것을 기반으로 합니다.
우리는 유니티의 AnimationCurve
시스템을 재사용하여 커브를 정의하고 있으며, 이를 FPAnimationCurve
이라고 하는 결정론적 버전으로 컴파일합니다.
사용자 고유의 커브를 작성할 때 가장 중요한 것은 고려 사항을 평가하는 방법을 올바르게 표현하는 커브를 사용하는 것입니다. 그것이 정말 특정한 값에 가까울 때만 중요한 행동일까요? 중요성이 선형적으로 증가합니까? 아니면 기하급수적으로요? 특정 범위 내에서 0일 수 있으며, 어느 정도 지나면 선형적으로 증가하기 시작할 수 있습니다.
사용자 고유의 커브를 작성하고 프리셋에서 원하는 커브를 선택한 다음 프리셋을 만듭니다.
명심해야할 중요한 개념은 커브의 Y축(결과 점수)을 정규화해야 합니다(즉, 0.1 사이). 이는 커브의 결과가 곱해지고 비율을 유지해야 하기 때문에 매우 중요합니다. 그렇지 않으면 커브의 결과가 서로 실제로 비교되지 않아 UT의 원리가 깨질 수 있습니다.
다음은 프리셋으로 저장되고 Spellcaster 샘플에 사용되는 반응 커브의 몇 가지 샘플 이미지입니다.
고려사항에 대한 반응 커브를 더 정의하려면 커브 영역을 두 번 클릭합니다. 커브 컨테이너로 이동합니다.
마우스 오른쪽 버튼을 사용하여 새 반응 커브를 작성합니다.
Click on the curve to open it's editor window.
어떤 커브를 사용할지는 게임별 요건에 따라 완전히 달라집니다. 해당 곡선에 삽입할 입력과 해당 입력 값의 변경 사항을 "유틸리티" 값에 반영하는 방법에 따라 달라집니다.
예를 들면 다음과 같습니다.
치유를 고려: 최대 체력이 10이고, 체력이 5 이하로 떨어지면 치유를 갈망하기 시작하는 에이전트가 있다고 가정해 보십시오. 따라서 5보다 큰 값에 대해서는 효용 곡선의 결과가 0이어야 합니다. 그러면, 0 미만의 값에 대해서는 치유의 효용성이 매우 빨리 증가하기를 바랍니다. 이것은 이를 올바르게 표현하는 곡선일 수 있습니다.
공격 고려: 시나리오에 적어도 한 명의 적이 있을 경우에만 공격하고자 하는 요원을 가정합니다. 적이 하나든 둘이든 열 명의 적이든 상관없습니다. 이 곡선은 "이진 임계값" 커브로, 0에서 1로 즉시 이동합니다. 커브로 표현되는 표현성을 일부 제거하더라도, 여전히 일부 유형의 분석에는 유용할 수 있습니다. 커브는 다음과 같습니다.
그런 다음 대가에 둘 이상의 반응 커브가 있는 것이 정상(필수는 아님)입니다. 필요에 따라 새 커브를 추가하기만 하면 됩니다. 커브에 사용되는 입력을 읽기 위해 추가되는 오버헤드를 주시하십시오(자세한 내용은 다음 주제 참조).
루트 뷰에서 반응 커브를 보고 편집할 수 있습니다.
응답 커브용 입력
입력 값은 게임마다 매우 다르기 때문에 사용자 지정 로직으로 정의됩니다. 엔티티의 컴포넌트에서 발생하는 상태 값일 수도 있고, 블랙보드에 저장된 데이터일 수도 있고, 일부 센서 시스템에서 수집된 데이터일 수도 있습니다.
사용자 고유의 입력 유형을 만들려면 AIFunctionFP
에서 상속하는 새 클래스를 만들고 Execute
메서드를 구현합니다.
C#
using Photon.Deterministic;
namespace Quantum
{
[System.Serializable]
public unsafe partial class InputEntityHealth : AIFunctionFP
{
public override FP Execute(Frame frame, EntityRef entity = default)
{
// Read the current health from the component which is in the Agent's entity
if(frame.TryGet<Health>(entity, out var health) == true)
{
return health.Current;
}
else
{
return 0;
}
}
}
}
Quantum 코드가 컴파일되면 콘텍스트 메뉴에서 기능 노드를 사용할 수 있습니다. 반응 커브 노드에 액세스하려면 고려 노드의 반응 커브 영역을 두 번 클릭합니다.
링크 고려
하나의 고려 사항을 다른 고려 사항과 연결하여 부모-자식 관계를 만들 수 있습니다.
이 경우 하위 고려사항은 특정 프레임에서 상위 고려사항이 가장 유용한 것으로 선택된 경우에만 평가됩니다. 그럴 때, 자식 고려는 형제자매들과만 경쟁할 것입니다.
이는 주로 두 가지 이유로 유용할 수 있습니다.:
- 성능 최적화에 도움이 될 수 있습니다. "싸움이 유용한지"를 분석하는 부모 고려와 어떤 전투 선택을 해야 할지 실제로 평가하는 자식들이 고려라고 상상해 보십시오. 전투에 유용할 때까지 계산되지 않습니다.
- 그러나 성능 문제에서 상위 고려사항에 포함된 곡선이 모든 하위 항목에 대해 암묵적으로 계산되는 것은 아니기 때문에 반복해서 커브를 다시 계산할 필요가 없습니다.
- 부모 고려사항 커브를 자식에게 복제할 필요가 없는 "상황별" 문제에서 고려사항을 구성하는 데 도움이 됩니다.
고려사항을 연결하려면 고려 노드의 출력 슬롯을 클릭하고 다른 사용자의 입력 슬롯에 연결하기만 하면 됩니다.
유틸리티 이론 AI 컴파일하기
생성한 UT를 실제로 사용하려면 작업을 컴파일해야 합니다.
컴파일하려면 두 가지 옵션이 있습니다.:
- 왼쪽 버튼은 현재 열려 있는 문서만 컴파일하는 데 사용됩니다.
- 오른쪽 버튼은 프로젝트에 있는 모든 AI 문서를 컴파일하는 데 사용됩니다.
UT 파일은 "Assets/Resources/DB/CircuitExport/UT_Assets"에 있습니다.
로봇에서 사용할 AI 설정
마지막으로 생성된 AI를 사용하려면 컴파일된 에셋만 참조하면 됩니다.
GUID를 기반으로 자산을 로드하거나 원하는 AI 자산을 가리키는 AssetRefUTRoot
를 생성하기만 하면 됩니다.
유틸리티 Reasoner
유틸리티 Reasoner는 Quantum 측면에서 모든 UT 아키텍처를 담당하는 주요 구조입니다. 점수 매기기 및 고려사항 선택과 관련된 모든 데이터가 들어 있습니다.
사유를 특정 엔터티에 연결하여 에이전트로 간주하려면 해당 엔터티에 UTAgent
라는 컴포넌트를 추가할 수 있습니다. 이것은 quantum 코드를 통해 수행하거나 엔티티 프로토타입에서 직접 수행할 수 있습니다. UTA 에이전트에는 유틸리티 Reasoner가 이미 포함되어 있습니다.
프로토타입에서 직접 작업할 경우 Unity에서 직접 UTRoot
에셋을 참조할 수 있다는 장점이 있으며, 이 기능은 유용할 수 있습니다.
Reasoner는 일반 Quantum 구조입니다. 다음 항목에서 설명하는 UTAgent
라는 컴포넌트가 사용하지만 DSL의 글로벌
데이터의 일부로 Reasoner를 선언할 수도 있습니다. 전체 UT API에는 EntityRef 엔티티
매개 변수가 옵션으로 있습니다. 이것은 모두 개체와 전혀 연결되지 않은 추론자(또는 그 이상)를 만들 수 있다는 것을 의미하며, 이는 생물체의 생성 장소/시기/방법을 결정한 RTS 게임에서 "가상 플레이어"와 같은 보다 추상적인 개념에 유용할 수 있습니다.
Reasoner를 글로벌 데이터의 일부로 사용하려면 다음과 같이 선언하고 참조하면 됩니다.
// In any DSL file
global
{
UtilityReasoner UtilityReasoner;
}
// In any other logic file, such as inside a System
f.Global->UtilityReasoner
초기화 및 갱신
다음은 UTAgent 구성 요소의 용례로 제시된 Utility Reasoner를 초기화하기 위한 코드입니다.
C#
UTManager.Init(f, &utAgent->UtilityReasoner, utAgent->UtilityReasoner.UTRoot, entity);
Utility Reasoner의 갱신에 대해서는:
C#
UTManager.Update(f, &utAgent->UtilityReasoner, entity);
필드 값 정의
고려 사항, 입력 사항, 순위 및 약속 필드에 값을 설정할 때 사용할 수 있는 대체 방법에 대한 자세한 내용은 여기를 참조하십시오.: 필드값 정의.
AIParam
수동 설정 또는 Blackboard/Constant/Config Nodes 설정 등 다양한 방법으로 정의할 수 있는 보다 유연한 필드를 원하는 경우 유용한 AIParam
유형의 사용 방법에 대한 자세한 내용은 여기를 참조하십시오: AIParam.
AIContext
에이전트 콘텍스트 정보를 파라미터로 전달하는 방법에 대한 자세한 내용은 여기를 참조하십시오:AIContext.
BotSDKSystem
Blackboard 메모리 할당 해제와 같은 일부 프로세스를 자동화하는 데 사용되는 클래스가 있습니다. 자세한 내용은 여기를 참조하십시오: BotSDKSystem.
비쥬얼 편집기 주석
비쥬얼 편집기의 주석 생성 방법은 다음을 참고하십시오: 비쥬얼 편집기 주석.
컴파일 내보내기 폴더를 변경
기본적으로 Bot SDK 컴파일에서 생성된 자산은 Assets/Resources/DB/CircuitExport
폴더에 저장됩니다. 내보내기 폴더를 변경할 수 있는 방법은 여기를 참조하십시오.: 내보내기 폴더 변경
저장된 기록 크기를 선택
Bot SDK 파일에 저장된 기록 항목의 양을 변경할 수 있습니다. 이 문제에 대한 자세한 내용은 여기를 참조하십시오. 저장 회수 이력 변경.
Back to top