mcpField
U
ue-state-trees

ue-state-trees

github.com/quodsoler開発4191.1k 回インストール4 週間前に更新
リポジトリ

ue-state-trees について

UE 5.8 の State Tree を使う開発者向けのリファレンススキルです。ノード作成からランタイム統合まで、検証済み API を作業別に整理し、非推奨の形式も示します。

主な機能

  1. 01State Tree のランタイム構成
  2. 02タスク、条件、評価器の作成
  3. 03実行コンテキストと非同期完了
  4. 04スキーマと外部データの設定
  5. 05コンポーネント、AI、Mass との統合

活用シーン

  1. 01カスタム State Tree タスクの実装
  2. 02インスタンスデータやコンテキストの問題調査
  3. 03ノード制限と遷移の設定
  4. 04Actor や Mass エンティティへの統合

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/quodsoler/unreal-engine-skills --skill ue-state-trees

インストール後、Claude Code で/ue-state-treesを入力して読み込まれたか確認します。

同梱ファイルreferences/state-tree-mass-integration.mdreferences/state-tree-patterns.md

詳細

UE State Trees

対象エンジン:UE 5.8。以下の API は 5.8 のヘッダーに基づいて確認済みです。以前の形式は「非推奨 — 使用しないでください」に記載しています。

State Tree は、UStateTree データアセットとして作成し、実行コンテキストを介して C++ から実行する、データ駆動型の階層ステートマシンです。ランタイム型は StateTreeModule(プラグイン StateTree)にあります。アクター向けのコンポーネントとスキーマは GameplayStateTreeModule(プラグイン GameplayStateTree)にあります。Mass エンティティの動作には、MassEntity、MassCore、MassSignals に加えて MassAIBehavior(プラグイン MassAI、5.8 では実験的機能)が必要です。使用するモジュールを .Build.cs の PublicDependencyModuleNames に追加してください。

コンテキスト

.agents/ue-project-context.md が存在する場合は読み込んでください(モジュール名、規約、有効なプラグイン、GAS/ネットワークの設定)。ファイルがなくても作業を中断しないでください。

依頼内容とコードベースから対象領域を特定してください。異なるコードにつながる解釈が複数考えられる場合に限り、質問してください。

依頼内容…参照先
ランタイムの構成、インスタンスデータ、コンテキストについてアーキテクチャ、実行コンテキスト
タスクの作成についてタスク
条件の作成、または遷移のゲート設定について条件
ユーティリティスコア、「最適な子ステートの選択」について考慮事項
ワールドデータをツリーに渡す方法について評価器、外部データ
ステートが変化するタイミングと方法について遷移、ステートの種類と選択
タグ駆動のシグナルをツリーに送る方法についてイベント
ポーリングではなく C++ コールバックに応答する方法についてデリゲート
アセットで使用可能なノードの制限についてスキーマ
アクターまたは AI コントローラーでツリーを実行する方法についてコンポーネントと AI のセットアップ
ティックのコスト削減/ツリーのスリープについてスケジュールされたティック
大量のエンティティについてMass エンティティの統合
コールバックまたは別のスレッドから処理を完了する方法について非同期完了

アーキテクチャ

UStateTree (UDataAsset)          IsReadyToRun() must be true before execution
  ├── UStateTreeSchema           which nodes and context data are allowed
  ├── States                     hierarchy of States/Groups/Linked/Subtree
  │     ├── Tasks                work performed while the state is active
  │     ├── EnterConditions      gate on selecting the state
  │     ├── Considerations       utility score used by selection behaviours
  │     └── Transitions          rules for leaving the state
  ├── Evaluators                 global data providers, tick before transitions
  └── Parameters                 FInstancedPropertyBag global parameters

ノードは UObject ではなく USTRUCT であり、すべてのノードの仮想関数は const です。インスタンスごとの可変状態は、FStateTreeInstanceData が所有する別のインスタンスデータ構造体に格納されます。このデータがフレームをまたいで保持されます。実行コンテキストは、このインスタンスデータ上に構築される短命なビューです。

型役割
UStateTreeコンパイル済みアセット。IsReadyToRun() でリンクの成功を確認します
FStateTreeInstanceData永続的なランタイムストレージ — コンテキストではなく、こちらを保持します
FStateTreeExecutionContext読み書き用のフルコンテキスト。ティックごとに構築します
FStateTreeReferenceUStateTree* とオーバーライドされたグローバルパラメーター
EStateTreeRunStatusRunning、Stopped、Succeeded、Failed、Unset
// MyTreeRunner.h — persistent storage on the owner
UPROPERTY(Transient)
FStateTreeInstanceData InstanceData;

// .cpp — one context per tick over the same instance data
FStateTreeExecutionContext Context(*this, *StateTreeAsset, InstanceData);
Context.SetCollectExternalDataCallback(
    FOnCollectStateTreeExternalData::CreateUObject(this, &UMyTreeRunner::CollectExternalData));

FStateTreeExecutionContext::FStartParameters StartParams;
StartParams.RandomSeed = 1234;
Context.Start(StartParams);
// later frames
Context.Tick(DeltaTime);

他のシステムの実行後に遷移を評価する必要がある場合は、Tick を分割できます。まず TickUpdateTasks(DeltaTime) を呼び出し、その後に TickTriggerTransitions() を呼び出してください。

実行コンテキスト

5.8 では、コンテキストが機能ごとに分かれています。コンパイルできる範囲で、最も制限の強いものを選んでください。

コンテキスト使用できる機能一般的な用途
FStateTreeReadOnlyExecutionContextGetOwner、GetWorld、GetStateTree、HasEventToProcess、IsValidGetDebugInfo のオーバーライド、ゲームプレイデバッガー
FStateTreeMinimalExecutionContextSendEvent、ScheduleNextTick、スケジュールされたティックのリクエストを追加ティックの外部からイベントを送信
FStateTreeExecutionContextStart/Stop/Tick、インスタンスデータ、外部データ、FinishTask、BindDelegate を追加ノード内でのあらゆる処理
FStateTreeWeakExecutionContext後でキャプチャする弱参照ハンドルラムダ、潜在アクション、タイマー
FStateTreeStrongExecutionContext弱参照コンテキストから解決したアクセスコールバック内で MakeStrongExecutionContext() を使用

FStateTreeMinimalExecutionContext は FStateTreeReadOnlyExecutionContext を、FStateTreeExecutionContext は FStateTreeMinimalExecutionContext を継承します。そのため、完全なコンテキストを受け取るノードメソッドから、その上位にあるすべての機能を呼び出せます。

非同期処理の完了

FStateTreeWeakExecutionContext(有効なコンテキストから構築)をキャプチャし、非同期処理が戻ったときにタスクを終了します。潜在タスクのテンプレート全体については、state-tree-patterns.md を参照してください。

const FStateTreeWeakExecutionContext WeakContext = Context.MakeWeakExecutionContext();
OnRequestFinished.AddLambda([WeakContext]()
{
    WeakContext.FinishTask(EStateTreeFinishTaskType::Succeeded);
});

ティック内では、タスクは Context.FinishTask(*this, EStateTreeFinishTaskType::Succeeded) を使うか、Tick から完了ステータスを返して自身を終了します。

スキーマ

スキーマは、アセットで使用できるノード構造体、クラス、コンテキストデータを宣言します。ノードをエディターに表示するには IsStructAllowed が必要です。そのため、カスタムノードは標準スキーマが受け入れる *CommonBase 構造体(FStateTreeTaskCommonBase、FStateTreeConditionCommonBase、FStateTreeEvaluatorCommonBase、FStateTreeConsiderationCommonBase、FStateTreePropertyFunctionCommonBase)から派生させてください。

スキーマ公開するコンテキストデータ
UStateTreeComponentSchemaActor(ContextActorClass のクラス)
UStateTreeAIComponentSchemaActor(デフォルトは APawn)と AIController
UMassStateTreeSchemaFMassStateTreeExecutionContext 経由の Mass エンティティデータ
// MyGameStateTreeSchema.h
#pragma once
#include "StateTreeSchema.h"
#include "StateTreeExecutionTypes.h"
#include "MyGameStateTreeSchema.generated.h"

UCLASS(BlueprintType, EditInlineNew, CollapseCategories, meta = (DisplayName = "My Game Schema"))
class MYGAME_API UMyGameStateTreeSchema : public UStateTreeSchema
{
    GENERATED_BODY()

protected:
    virtual bool IsStructAllowed(const UScriptStruct* InScriptStruct) const override;
    virtual bool IsClassAllowed(const UClass* InScriptStruct) const override;
    virtual bool IsExternalItemAllowed(const UStruct& InStruct) const override;
    virtual TConstArrayView<FStateTreeExternalDataDesc> GetContextDataDescs() const override;

#if WITH_EDITOR
    virtual bool AllowEvaluators() const override { return true; }
    virtual bool AllowMultipleTasks() const override { return true; }
    virtual bool AllowGlobalParameters() const override { return true; }
    virtual bool AllowUtilityConsiderations() const override { return true; }
#endif

    UPROPERTY()
    TArray<FStateTreeExternalDataDesc> ContextDataDescs;
};

AllowEnterConditions、AllowUtilityConsiderations、AllowEvaluators、AllowMultipleTasks、AllowGlobalParameters、AllowTasksCompletion、AllowQueuedCompilation は #if WITH_EDITOR 内で宣言されています(StateTreeSchema.h:96-138)。これらはエディター/コンパイラーのみを制御するため、オーバーライドにも同じガードを付ける必要があります。付けない場合、ゲームビルドで「does not override」エラーが発生します。IsStructAllowed、IsClassAllowed、IsExternalItemAllowed、IsScheduledTickAllowed、IsStateSelectionAllowed、IsStateTypeAllowed、GetContextDataDescs はランタイム仮想関数です(StateTreeSchema.h:36-79)。

タスク

各タスクは、必要な仮想関数と GetInstanceDataType() をオーバーライドする必要があります。using FInstanceDataType = …; エイリアスだけでは何も割り当てられません。FStateTreeNodeBase::GetInstanceDataType() はデフォルトで nullptr を返し(StateTreeNodeBase.h:94)、コンパイラはストレージを予約しないため、Context.GetInstanceData(*this) を呼び出すと check(Memory != nullptr)(PropertyBindingDataView.h:116)に到達します。

仮想関数(シグネチャそのまま)戻り値
EnterState(FStateTreeExecutionContext& Context, const FStateTreeTransitionResult& Transition) constEStateTreeRunStatus
ExitState(FStateTreeExecutionContext& Context, const FStateTreeTransitionResult& Transition) constvoid
StateCompleted(FStateTreeExecutionContext& Context, const EStateTreeRunStatus CompletionStatus, const FStateTreeActiveStates& CompletedActiveStates) constvoid
Tick(FStateTreeExecutionContext& Context, const float DeltaTime) constEStateTreeRunStatus
TriggerTransitions(FStateTreeExecutionContext& Context) constvoid
GetDebugInfo(const FStateTreeReadOnlyExecutionContext& Context) constFString
// MyTimedTask.h
#pragma once
#include "StateTreeTaskBase.h"
#include "StateTreeExecutionContext.h"
#include "MyTimedTask.generated.h"

USTRUCT()
struct FMyTimedTaskInstanceData
{
    GENERATED_BODY()

    UPROPERTY(EditAnywhere, Category = "Parameter")
    float Duration = 2.0f;

    UPROPERTY()
    float ElapsedTime = 0.f;
};

USTRUCT(meta = (DisplayName = "My Timed Task"))
struct FMyTimedTask : public FStateTreeTaskCommonBase
{
    GENERATED_BODY()

    using FInstanceDataType = FMyTimedTaskInstanceData;

    virtual const UStruct* GetInstanceDataType() const override { return FInstanceDataType::StaticStruct(); }

    virtual EStateTreeRunStatus EnterState(FStateTreeExecutionContext& Context,
        const FStateTreeTransitionResult& Transition) const override
    {
        FInstanceDataType& Data = Context.GetInstanceData(*this);
        Data.ElapsedTime = 0.f;
        return EStateTreeRunStatus::Running;
    }

    virtual EStateTreeRunStatus Tick(FStateTreeExecutionContext& Context,
        const float DeltaTime) const override
    {
        FInstanceDataType& Data = Context.GetInstanceData(*this);
        Data.ElapsedTime += DeltaTime;
        return Data.ElapsedTime >= Data.Duration
            ? EStateTreeRunStatus::Succeeded
            : EStateTreeRunStatus::Running;
    }
};

編集可能なパラメーターは通常、エディターでバインドできるようインスタンスデータに配置します。ノード構造体自体に置いたプロパティはすべてのインスタンスで共有され、バインドできません。

動作フラグ

タスクのコンストラクターで設定します。

フラグデフォルト効果
bShouldStateChangeOnReselecttrue同じステートが再び選択されたときに、Exit/Enterを再実行します
bShouldCallTicktrueTick() を呼び出します。falseの場合、プロパティのコピーも無効になります
bShouldCallTickOnlyOnEventsfalseイベントがあるフレームでのみTickします(bShouldCallTick がfalseである必要があります)
bShouldCopyBoundPropertiesOnTicktrueTick() の前にバインドされたプロパティを更新します
bShouldCopyBoundPropertiesOnExitStatetrueExitState() の前にバインドされたプロパティを更新します
bShouldAffectTransitionsfalse遷移処理中に TriggerTransitions() を呼び出します
bConsideredForSchedulingtrueスケジュールされたTickレートの計算にこのタスクを含めます
bTaskEnabledtrueアセット内でノードが無効化されていません

TransitionHandlingPriority(EStateTreeTransitionPriority)は、1つのステートに属するタスク間で TriggerTransitions の順序を決定します。

条件

FStateTreeConditionBase::TestCondition(FStateTreeExecutionContext& Context) const は bool を返し、デフォルトでは false です。この関数は副作用のない処理にする必要があります。選択パスでは、1フレーム中に複数回呼び出されることがあります。

メンバー目的
EStateTreeExpressionOperand OperandCopy、And、Or、Multiply(Multiply は考慮事項のみ)
int8 DeltaIndent括弧のレベル。ネストせずに (A AND B) OR (C AND D) を表します
EStateTreeConditionEvaluationMode EvaluationModeEvaluated、ForcedTrue、ForcedFalse

条件には EnterState、ExitState、StateCompleted も用意されています(デフォルトではすべて何もしません)。これにより、ステートの存続期間を通じて処理をキャッシュできます。

標準の条件には、FStateTreeCompareIntCondition、FStateTreeCompareFloatCondition、FStateTreeCompareBoolCondition、FStateTreeCompareEnumCondition、FStateTreeCompareNameCondition、FStateTreeCompareDistanceCondition、FStateTreeRandomCondition(Conditions/StateTreeCommonConditions.h)、FStateTreeObjectIsValidCondition(Conditions/StateTreeObjectConditions.h)、および Conditions/StateTreeGameplayTagConditions.h のGameplay Tag関連の条件群があります。比較条件は UE::StateTree::EComparisonOperator を受け取ります。

留意点

考慮項目は状態をスコアリングし、親が子の中から選択できるようにします。API はヘッダーで実験的とされているため、独自の考慮項目は小規模に保ってください。

USTRUCT(meta = (DisplayName = "My Threat Score"))
struct FMyThreatConsideration : public FStateTreeConsiderationCommonBase
{
    GENERATED_BODY()

    using FInstanceDataType = FMyThreatConsiderationInstanceData;

    virtual const UStruct* GetInstanceDataType() const override { return FInstanceDataType::StaticStruct(); }

protected:
    virtual float GetScore(FStateTreeExecutionContext& Context) const override
    {
        const FInstanceDataType& Data = Context.GetInstanceData(*this);
        return FMath::Clamp(Data.ThreatLevel / 100.f, 0.f, 1.f);
    }
};

GetScore は protected です。フレームワークは公開メソッドの GetNormalizedScore を呼び出します。Operand と DeltaIndent は兄弟の考慮項目を組み合わせます(And = 最小値、Or = 最大値、Multiply = 積)。スコアが関係するのは 2 つのユーティリティ選択動作のみで、スキーマの AllowUtilityConsiderations() は true を返す必要があります。

評価関数

評価関数はグローバル(状態ごとではありません)で、遷移およびタスクのティックより前にティックされます。多くのノードが読み取るデータには評価関数を使用し、安定した参照には外部データを使用してください。

virtual void TreeStart(FStateTreeExecutionContext& Context) const;
virtual void TreeStop(FStateTreeExecutionContext& Context) const;
virtual void Tick(FStateTreeExecutionContext& Context, const float DeltaTime) const;
virtual FString GetDebugInfo(const FStateTreeReadOnlyExecutionContext& Context) const;

状態の事前選択中に評価関数がティックされる場合、DeltaTime は 0 です。評価関数にもタスクとまったく同じ GetInstanceDataType() が必要です。テンプレート全体は state-tree-patterns.md にあります。

遷移

EStateTreeTransitionTrigger はビットマスクです(ENUM_CLASS_FLAGS)。

トリガー値発生条件
OnStateSucceeded0x1状態が Succeeded で完了したとき
OnStateFailed0x2状態が Failed で完了したとき
OnStateCompleted0x1|0x2上記のいずれか
OnTick0x4毎ティック — 必ず条件で制御してください
OnEvent0x8キューに入ったイベントのタグが一致したとき
OnDelegate0x10バインドされたデリゲートがブロードキャストされたとき

EStateTreeTransitionPriority:Low、Normal、Medium、High、Critical。優先度が最も高い、最初にトリガーされた遷移が選択されます。遷移の種類(EStateTreeTransitionType):None、Succeeded、Failed、GotoState、Parent、NextState、NextSelectableState、NextParent、NextSelectableParent(StateTreeTypes.h:76)。遷移ごとのフラグ bTransitionEnabled と bConsumeEventOnSelect は、どちらもデフォルトで true です。

C++ からは、Context.RequestTransition(TargetState, Priority, Fallback) で遷移を要求します。Fallback は EStateTreeSelectionFallback です。

デリゲート

外部システムからツリーに反応するタイミングを正確に通知できる場合、デリゲートを使うことでポーリングを置き換えられます。あるノードがインスタンスデータ上で FStateTreeDelegateDispatcher を公開し、別のノードが FStateTreeDelegateListener を公開します。エディターでこの 2 つを接続します。

// On the listening node's instance data
UPROPERTY(EditAnywhere, Category = "Input")
FStateTreeDelegateListener ArrivedListener;

// EnterState — bind
Context.BindDelegate(Data.ArrivedListener, FSimpleDelegate::CreateLambda([]()
{
    UE_LOG(LogMyGame, Verbose, TEXT("Arrived"));
}));

// ExitState — always unbind
Context.UnbindDelegate(Data.ArrivedListener);

// On the dispatching node
Context.BroadcastDelegate(Data.ArrivedDispatcher);

OnDelegate トリガーを持つ遷移は、バインドされたディスパッチャーがブロードキャストされると、ほかの遷移と併せて評価されます。

状態の種類と選択

EStateTreeStateType:State、Group、Linked、LinkedAsset、Subtree。LinkedAsset 状態は共有の仕組みです。FStateTreeReferenceOverrides を使って、インスタンスごとにオーバーライドできます。

EStateTreeStateSelectionBehavior:

動作効果
None状態を直接選択できません
TryEnterState子があってもこの状態に入ります
TrySelectChildrenInOrder入場条件を満たす最初の子を選択します
TrySelectChildrenAtRandom子をシャッフルし、条件を満たす最初の子を選択します
TrySelectChildrenWithHighestUtility最も高い考慮項目スコアを選択し、同点の場合は順序で決定します
TrySelectChildrenAtRandomWeightedByUtility正規化されたスコアを重みとしてランダムに選択します
TryFollowTransitions状態に入る代わりに、その状態の遷移を評価します

FStateTreeActiveStates::MaxStates = 8 により、アクティブな状態パスの深さが制限されます。より深い設計はサブツリーまたはリンクされたアセットで平坦化してください。

イベント

イベントは、任意のペイロードを持つゲームプレイタグメッセージです:FStateTreeEvent { FGameplayTag Tag; FInstancedStruct Payload; FName Origin; }。

// From outside the tree
StateTreeComp->SendStateTreeEvent(MyTag_AiAlert, FConstStructView::Make(AlertData), TEXT("Perception"));

// From inside a node (available on the minimal context and above)
Context.SendEvent(MyTag_AiAlert, FConstStructView::Make(ResultData), TEXT("MyTask"));

インスタンスごとの FStateTreeEventQueue::MaxActiveEvents = 64 です。Context.ForEachEvent(Lambda) で反復処理します。ラムダは EStateTreeLoopEvents(Next、Break、Consume — StateTreeEvents.h:35)を返し、Context.ConsumeEvent(SharedEvent) でイベントを 1 つ削除します(戻り値は void)。Context.HasEventToProcess(Tag) は、イベントの有無を低コストで確認できます。ゲームプレイタグの宣言場所については、ue-gameplay-tags-messaging を参照してください。

外部データ

外部データを使うと、ノードはスキーマの所有者が提供するオブジェクトまたは構造体(サブシステム、所有者のアクター、コンポーネント)への、型付き参照を取得できます。

TStateTreeExternalDataHandle<UMyWorldSubsystem> SubsystemHandle;
TStateTreeExternalDataHandle<AActor, EStateTreeExternalDataRequirement::Optional> ActorHandle;

virtual bool Link(FStateTreeLinker& Linker) override
{
    Linker.LinkExternalData(SubsystemHandle);
    Linker.LinkExternalData(ActorHandle);
    return true;
}

// Required handles return a reference, Optional handles a pointer
UMyWorldSubsystem& Subsystem = Context.GetExternalData(SubsystemHandle);
AActor* Actor = Context.GetExternalDataPtr(ActorHandle);

Link は bool を返します(基底クラスでは [[nodiscard]]、StateTreeNodeBase.h:116)。リンクに成功した場合は true、失敗した場合は false を返します。

UStateTreeComponentSchema::IsExternalItemAllowed が受け入れるのは、AActor、UActorComponent、UWorldSubsystem のサブクラスのみです。所有者のアクターは、Actor という名前の コンテキストデータ として別途公開されます(AI スキーマの場合は AIController も公開されます)。これにアクセスする標準的な方法は、エディターが自動的にバインドするインスタンスデータプロパティです。

UPROPERTY(EditAnywhere, Category = "Context")
TObjectPtr<AActor> Actor = nullptr;

エンジンに FStateTreeActorContext 型はありません。上記の方法を使ってください。

コンポーネントと AI の設定

UStateTreeComponent : UBrainComponent, IGameplayTaskOwnerInterface, IStateTreeSchemaProvider は、アクター上で 1 つのツリーを実行します。UStateTreeAIComponent はこれを継承し、UStateTreeAIComponentSchema を返します。このスキーマは AAIController のコンテキスト値を保証するため、AI コントローラーで使用してください。

// MyAIController.h — inside the AMyAIController class body
UPROPERTY(VisibleAnywhere, Category = "AI")
TObjectPtr<UStateTreeAIComponent> StateTreeComp;

// MyAIController.cpp
AMyAIController::AMyAIController()
{
    StateTreeComp = CreateDefaultSubobject<UStateTreeAIComponent>(TEXT("StateTree"));
    StateTreeComp->SetStartLogicAutomatically(true);
}

bStartLogicAutomatically は protected です。SetStartLogicAutomatically(const bool) を通して設定してください。公開されているインターフェースは、SetStateTree、SetStateTreeReference、AddLinkedStateTreeOverrides(FGameplayTag, FStateTreeReference)、RemoveLinkedStateTreeOverrides(FGameplayTag)、SendStateTreeEvent、GetStateTreeRunStatus、および BlueprintAssignable な OnStateTreeRunStatusChanged です。StartLogic、StopLogic、PauseLogic、ResumeLogic は UBrainComponent から提供されます。

SetContextRequirements(FStateTreeExecutionContext& Context, bool bLogErrors)/CollectExternalData(const FStateTreeExecutionContext& Context, const UStateTree* StateTree, TArrayView<const FStateTreeExternalDataDesc> Descs, TArrayView<FStateTreeDataView> OutDataViews) const をサブクラスでオーバーライドして、追加のコンテキストや外部データを公開します。

FStateTreeReference
FStateTreeReference TreeRef;
TreeRef.SetStateTree(MyStateTreeAsset);          // also calls SyncParameters()
TreeRef.GetMutableParameters().SetValueFloat(TEXT("AggroRange"), 1500.f);
StateTreeComp->SetStateTreeReference(TreeRef);

GetParameters() は const FInstancedPropertyBag& を返します。変更するには GetMutableParameters() を使用してください。

スケジュールされたティック

アクティブなタスクがすべてティックを無効にしているツリーは、毎フレーム実行する代わりにスリープできます。FStateTreeScheduledTick::MakeSleep()、MakeNextFrame()、MakeEveryFrames()、MakeCustomTickRate(DeltaTime) で希望する実行間隔を指定します。FStateTreeMinimalExecutionContext::AddScheduledTickRequest/UpdateScheduledTickRequest/RemoveScheduledTickRequest でリクエストを管理し、ScheduleNextTick() でツリーを再開します。UStateTreeComponent は FStateTreeComponentExecutionExtension を通じてこれを実装しており、UStateTreeComponentSchema::IsScheduledTickAllowed() と StateTree.Component.DefaultScheduledTickAllowed コンソール変数によって制御されます。カウント対象にしないタスクは bConsideredForScheduling = false を設定します。

独自のランナーでインスタンスごとの説明とカスタムのティック スケジューリングを行うには、FStateTreeExecutionExtension(GetInstanceDescription、ScheduleNextTick、OnLinkedStateTreeOverridesSet、OnBeginApplyTransition)を実装し、FStartParameters::ExecutionExtension に渡してください。

Mass Entity の統合

Mass のビヘイビアでは UMassStateTreeSchema と、FMassStateTreeTaskBase、FMassStateTreeConditionBase、FMassStateTreeEvaluatorBase のノード型を使用します。これらの型は GetDependencies(UE::MassBehavior::FStateTreeDependencyBuilder&) const を追加しており、動的に作成される UMassStateTreeProcessor(UMassSignalProcessorBase)が適切なフラグメントクエリを構築できるようにします。完全な設定、フラグメントテーブル、シグナル名、プロセッサーのフローについては、state-tree-mass-integration.md を参照してください。Mass のアーキテクチャ自体については、ue-mass-entity を参照してください。

非推奨 — 使用しないでください

出力しないでください5.8 で使用ソース
Start(const FInstancedPropertyBag*, int32 RandomSeed)Start(FStartParameters)StateTreeExecutionContext.h:492 の UE_DEPRECATED(5.8)
AppendDebugInfoString(FString&, const FStateTreeExecutionContext&)GetDebugInfo(const FStateTreeReadOnlyExecutionContext&)StateTreeEvaluatorBase.h:44 の UE_DEPRECATED(5.8)
比較条件での EGenericAICheck 演算子UE::StateTree::EComparisonOperatorConditions/StateTreeCommonConditions.h:47 の UE_DEPRECATED(5.8)
STATETREE_POD_INSTANCEDATA(Type)UE_STATETREE_ZEROED_TRIVIALLY_COPIED_NO_DESTRUCTOR_INSTANCEDATA(Type)(または _CONSTRUCTED_ バリアント)StateTreeTypes.h:1388 の UE_DEPRECATED_MACRO(5.8)
FStateTreePropertyRefExternalHandle実行コンテキスト経由で読み取る FStateTreePropertyRefStateTreePropertyRef.h:295 の UE_DEPRECATED(5.8)
AddDelegateListener(Listener, Delegate)BindDelegate(Listener, Delegate)StateTreeExecutionContext.h:530 の UE_DEPRECATED(5.6)
RemoveDelegateListener(Listener)UnbindDelegate(Listener)StateTreeExecutionContext.h:541 の UE_DEPRECATED(5.6)
FinishTask(const UE::StateTree::FFinishedTask&, EStateTreeFinishTaskType)FinishTask(const FStateTreeTaskBase&, EStateTreeFinishTaskType)StateTreeExecutionContext.h:790 の UE_DEPRECATED(5.6)
FStateTreeWeakTaskRef / FStateTreeStrongTaskRefFStateTreeWeakExecutionContextStateTreeNodeRef.h:15,51 の UE_DEPRECATED(5.6)
OnBindingChanged(…, const FStateTreePropertyPath&, …)FPropertyBindingPath オーバーロードStateTreeNodeBase.h:186 の UE_DEPRECATED(5.6)
TrySelectChildrenAtUniformRandomTrySelectChildrenAtRandomStateTreeTypes.h:196 の UE_DEPRECATED(all)
TrySelectChildrenBasedOnRelativeUtilityTrySelectChildrenAtRandomWeightedByUtilityStateTreeTypes.h:197 の UE_DEPRECATED(all)
Compile(FStateTreeDataView, TArray<FText>&)Compile(UE::StateTree::ICompileNodeContext&)StateTreeNodeBase.h:141 の UE_DEPRECATED(5.6) final スタブ
StateTreeComp->bStartLogicAutomatically = true;StateTreeComp->SetStartLogicAutomatically(true);Components/StateTreeComponent.h:187 で protected
TreeRef.GetParameters().SetValueFloat(…)TreeRef.GetMutableParameters().SetValueFloat(…)StateTreeReference.h:61 の const アクセサー
FStateTreeActorContextTStateTreeExternalDataHandle<AActor> または Category = "Context" のインスタンスデータプロパティエンジンにこの型はありません

よくある間違い

GetInstanceDataType() を省略する: State Tree で最もよくあるバグです。using FInstanceDataType = …; は型を文書化するだけで、ストレージを登録するのはオーバーライドだけです。

using FInstanceDataType = FMyTaskInstanceData;
virtual const UStruct* GetInstanceDataType() const override { return FInstanceDataType::StaticStruct(); }

実行コンテキストを保存する: 実行コンテキストは、FStateTreeInstanceData 上のティックごとのビューです。インスタンスデータは所有者の UPROPERTY(Transient) として保持し、毎ティックコンテキストを再構築してください。後で使う必要がある場合は、FStateTreeWeakExecutionContext をキャプチャしてください。

ノード構造体を変更する: すべてのノードの仮想関数は const なので、メンバーに対する Timer += DeltaTime; はコンパイルできません。Context.GetInstanceData(*this) に書き込んでください。

FStateTreeTaskBase から直接派生する: 標準のスキーマで許可されるのは FStateTreeTaskCommonBase とその派生型だけなので、ノードはエディターの選択画面に表示されません。スキーマで受け入れられる *CommonBase 構造体(または Mass/AI の基底型)から派生してください。

スキーマの Allow* オーバーライドを #if WITH_EDITOR で囲まない: 基底型ではこれらはエディター専用として宣言されています(StateTreeSchema.h:96)。そのため、ガードなしの override はエディターではコンパイルできますが、Game/Shipping ターゲットでは失敗します。

TestCondition で副作用を発生させる: 選択処理では、同じフレーム内に同じ条件が複数回テストされることがあります。条件は純粋に保ち、代わりに条件の EnterState で値をキャッシュしてください。

デリゲートのバインドを解除しない: EnterState での BindDelegate には、ExitState での UnbindDelegate が必要です。そうしないと、アクティブでなくなった状態に対してリスナーが呼び出されます。

MaxStates を超える: アクティブな状態パスの上限は 8 です。それより深い階層では、明確な警告が出るのではなく選択に失敗します。

Tick が実行されると思い込む: bShouldCallTick = false の場合、またはスケジュールされたティックによってツリーがスリープ状態になると、タスクはティックされず、バインドされたプロパティもコピーされません。これらのタスクはイベントまたはデリゲートから実行してください。

関連スキル

  • ue-ai-navigation — ビヘイビアツリー、知覚、EQS、ナビゲーション、Smart Objects
  • ue-mass-entity — Mass プロセッサ、フラグメント、トレイト、エンティティクエリ
  • ue-gameplay-abilities — 状態変化を駆動または検知するアビリティとエフェクト
  • ue-gameplay-framework — ツリーに関連するコントローラー、ポーン、ゲームモードのライフサイクル
  • ue-actor-component-architecture — コンポーネントの所有権、ティック、レプリケーションの設定
  • ue-cpp-foundations — USTRUCT のルール、デリゲート、サブシステムへのアクセス
  • ue-gameplay-tags-messaging — State Tree のイベントと遷移で使うゲームプレイタグの宣言
  • ue-gameplay-cameras — スプリングアーム、ビュ―ターゲット、カメラモディファイアー、シェイク、Gameplay Camera System

コメント