ue-state-trees について
UE 5.8 の State Tree を使う開発者向けのリファレンススキルです。ノード作成からランタイム統合まで、検証済み API を作業別に整理し、非推奨の形式も示します。
主な機能
- 01State Tree のランタイム構成
- 02タスク、条件、評価器の作成
- 03実行コンテキストと非同期完了
- 04スキーマと外部データの設定
- 05コンポーネント、AI、Mass との統合
活用シーン
- 01カスタム State Tree タスクの実装
- 02インスタンスデータやコンテキストの問題調査
- 03ノード制限と遷移の設定
- 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 | 読み書き用のフルコンテキスト。ティックごとに構築します |
FStateTreeReference | UStateTree* とオーバーライドされたグローバルパラメーター |
EStateTreeRunStatus | Running、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 では、コンテキストが機能ごとに分かれています。コンパイルできる範囲で、最も制限の強いものを選んでください。
| コンテキスト | 使用できる機能 | 一般的な用途 |
|---|---|---|
FStateTreeReadOnlyExecutionContext | GetOwner、GetWorld、GetStateTree、HasEventToProcess、IsValid | GetDebugInfo のオーバーライド、ゲームプレイデバッガー |
FStateTreeMinimalExecutionContext | SendEvent、ScheduleNextTick、スケジュールされたティックのリクエストを追加 | ティックの外部からイベントを送信 |
FStateTreeExecutionContext | Start/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)から派生させてください。
| スキーマ | 公開するコンテキストデータ |
|---|---|
UStateTreeComponentSchema | Actor(ContextActorClass のクラス) |
UStateTreeAIComponentSchema | Actor(デフォルトは APawn)と AIController |
UMassStateTreeSchema | FMassStateTreeExecutionContext 経由の 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) const | EStateTreeRunStatus |
ExitState(FStateTreeExecutionContext& Context, const FStateTreeTransitionResult& Transition) const | void |
StateCompleted(FStateTreeExecutionContext& Context, const EStateTreeRunStatus CompletionStatus, const FStateTreeActiveStates& CompletedActiveStates) const | void |
Tick(FStateTreeExecutionContext& Context, const float DeltaTime) const | EStateTreeRunStatus |
TriggerTransitions(FStateTreeExecutionContext& Context) const | void |
GetDebugInfo(const FStateTreeReadOnlyExecutionContext& Context) const | FString |
// 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;
}
};
編集可能なパラメーターは通常、エディターでバインドできるようインスタンスデータに配置します。ノード構造体自体に置いたプロパティはすべてのインスタンスで共有され、バインドできません。
動作フラグ
タスクのコンストラクターで設定します。
| フラグ | デフォルト | 効果 |
|---|---|---|
bShouldStateChangeOnReselect | true | 同じステートが再び選択されたときに、Exit/Enterを再実行します |
bShouldCallTick | true | Tick() を呼び出します。falseの場合、プロパティのコピーも無効になります |
bShouldCallTickOnlyOnEvents | false | イベントがあるフレームでのみTickします(bShouldCallTick がfalseである必要があります) |
bShouldCopyBoundPropertiesOnTick | true | Tick() の前にバインドされたプロパティを更新します |
bShouldCopyBoundPropertiesOnExitState | true | ExitState() の前にバインドされたプロパティを更新します |
bShouldAffectTransitions | false | 遷移処理中に TriggerTransitions() を呼び出します |
bConsideredForScheduling | true | スケジュールされたTickレートの計算にこのタスクを含めます |
bTaskEnabled | true | アセット内でノードが無効化されていません |
TransitionHandlingPriority(EStateTreeTransitionPriority)は、1つのステートに属するタスク間で TriggerTransitions の順序を決定します。
条件
FStateTreeConditionBase::TestCondition(FStateTreeExecutionContext& Context) const は bool を返し、デフォルトでは false です。この関数は副作用のない処理にする必要があります。選択パスでは、1フレーム中に複数回呼び出されることがあります。
| メンバー | 目的 |
|---|---|
EStateTreeExpressionOperand Operand | Copy、And、Or、Multiply(Multiply は考慮事項のみ) |
int8 DeltaIndent | 括弧のレベル。ネストせずに (A AND B) OR (C AND D) を表します |
EStateTreeConditionEvaluationMode EvaluationMode | Evaluated、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)。
| トリガー | 値 | 発生条件 |
|---|---|---|
OnStateSucceeded | 0x1 | 状態が Succeeded で完了したとき |
OnStateFailed | 0x2 | 状態が Failed で完了したとき |
OnStateCompleted | 0x1|0x2 | 上記のいずれか |
OnTick | 0x4 | 毎ティック — 必ず条件で制御してください |
OnEvent | 0x8 | キューに入ったイベントのタグが一致したとき |
OnDelegate | 0x10 | バインドされたデリゲートがブロードキャストされたとき |
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::EComparisonOperator | Conditions/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 | 実行コンテキスト経由で読み取る FStateTreePropertyRef | StateTreePropertyRef.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 / FStateTreeStrongTaskRef | FStateTreeWeakExecutionContext | StateTreeNodeRef.h:15,51 の UE_DEPRECATED(5.6) |
OnBindingChanged(…, const FStateTreePropertyPath&, …) | FPropertyBindingPath オーバーロード | StateTreeNodeBase.h:186 の UE_DEPRECATED(5.6) |
TrySelectChildrenAtUniformRandom | TrySelectChildrenAtRandom | StateTreeTypes.h:196 の UE_DEPRECATED(all) |
TrySelectChildrenBasedOnRelativeUtility | TrySelectChildrenAtRandomWeightedByUtility | StateTreeTypes.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 アクセサー |
FStateTreeActorContext | TStateTreeExternalDataHandle<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 Objectsue-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