UnitySampleは、Unity向けの拡張機能やサンプルコードを集約したプロジェクトです。
SyncAsyncFSM
- 同期・非同期を統合管理するステートマシン(Finite State Machine)MaterialPropertyApplier
- マテリアルプロパティをゲームオブジェクトごとに変更するためのエディタ拡張
SyncAsyncFSM<TOwner>
は、同期処理SyncState
と非同期処理AsyncState
を同一フレームワークで管理できる汎用ステートマシンです。ゲームオブジェクトの状態遷移や、状態に応じた非同期イベント管理に適しています。
Assets/Scenes/FsmDemo.unity
SyncState
(同期)とAsyncState
(非同期)の明確な区別- 条件付き遷移(ゲート関数によるフィルタリング)
- 任意遷移
AnyState
や直前復帰PreviousState
をサポート - 遷移予約
Schedule
と即時遷移Dispatch
の両対応 - UniTaskに対応
Cysharp.Threading.Tasks
- FSMの初期化・起動・更新
FSMを所有するクラスMyOwner
を型引数に持つFSMSyncAsyncFSM<MyOwner>
を宣言します。
public class MyOwner : Monobehavior
{
private SyncAsyncFSM<MyOwner> fsm;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
// 初期化
// 所有者のインスタンスを引数に渡す
fsm = new SyncAsyncFSM<MyOwner>(this);
// 2.ここで遷移登録
// 起動
// はじめのステートを型引数に渡す
fsm.Start<IdleState>();
}
// Update is called once per frame
void Update()
{
// 更新
fsm.Update();
}
// 3.ここからステートを定義
}
- 遷移登録
各ステートはそれぞれ遷移テーブルを持っており、イベントIDint
,遷移先Type
,遷移条件Func<bool>
を追加することで遷移を登録します。
💡 登録した順に遷移が優先されます。
💡 任意遷移を登録するにはTFrom
にSyncAsyncState<MyOwner>.AnyState
を指定します。
💡 直前復帰を登録するにはTTo
にSyncAsyncState<MyOwner>.PreviousState
を指定します。
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
// 1.初期化
// 遷移登録
fsm.AddTransition<IdleState, EntryState>(1);
fsm.AddTransition<EntryState, ExploreState>(2);
fsm.AddTransition<ExploreState, DiscoverState>(3);
fsm.AddTransitionRange<DiscoverState>(
(4, typeof(ExploreState), () => treasureCount < 3),
(5, typeof(IdleState), () => true));
fsm.AddTransition<SyncAsyncFSM<MyOwner>.AnyState, MenuState>(6, () => fsm.CurrentState.GetType() != typeof(MenuState));
fsm.AddTransition<MenuState, SyncAsyncFSM<DungeonRunner>.PreviousState>(7);
// 1.起動
}
void AddTransition<TFrom, TTo>(int eventId, Func<bool> gate);
指定されたイベントIDを契機として、TFrom
からTTo
への遷移を登録します。遷移には条件(ゲート)を付随できます。
void AddTransition<TFrom, TTo>(int eventId);
常に有効な遷移(ゲートなし)を登録する簡易版。
void AddTransition<TFrom>(params (int eventId, Type toType, Func<bool> gate)[] to);
遷移元ステートTFrom
に対し、複数の遷移先を一括で登録できます。各遷移には条件を指定可能です。
void AddTransition<TFrom>(params (int eventId, Type toType, Func<bool> gate)[] to);
条件なしで複数の遷移を一括登録する簡易版。
- ステートを定義
同期ステートを定義するにはSyncAsyncFSM<MyOwner>.SyncState
を継承させる必要があります
public class IdleState : SyncAsyncFSM<MyOwner>.SyncState
{
// このステートに遷移直後に一度呼ばれる
public override void Enter()
{
}
public override void Update()
{
// 状態ロジック
}
// 他のステートへ遷移直前に一度呼ばれる
public override void Exit()
{
}
}
非同期ステートを定義するにはSyncAsyncFSM<MyOwner>.AsyncState
を継承させる必要があります
public class EntryState : SyncAsyncFSM<MyOwner>.AsyncState
{
public override async UniTask Start(Cancellation token)
{
// 状態ロジック
}
// このステートが終了する前に他のステートへ遷移するときや、このFSMを所有するクラスが破棄されたときに呼ばれる
public override void OnCancel()
{
}
}
MyOwner Owner;
ステートクラス内でもOwner
のインスタンスを取得できます。
- 遷移の予約・実行
void Schedule(int eventId);
現在のステートの遷移テーブルに指定されたイベントIDが登録されていればその遷移が予約されます。
void ScheduleAll();
現在のステートに登録されている遷移をすべて予約します。
void Dispatch();
予約されている遷移の中から優先度順(登録された順)で遷移条件を満たせば遷移が実行されます。実行されなかった予約済みの遷移は破棄されます。
void Dispatch(int eventId);
予約済みの遷移を破棄して指定されたイベントIDの遷移を遷移条件を満たせば実行します。
MaterialPropertyApplier
はマテリアルプロパティ(Int
・Float
・FloatArray
・Texture
・Color
)をMaterialPropertyBlock
を通して動的に変更するためのエディタ拡張です。
Assets/Scenes/MpaDemo.unity
MaterialPropertyBlock
を使うことでマテリアルのインスタンスを作成することなくゲームオブジェクトごとに変更- エディタ上で変更・確認が可能
- GameObjectにアタッチ
任意のGameObjectにMaterialPropertyApplier
コンポーネントをアタッチします。
- Inspectorでプロパティ設定
Inspector上で以下のようなプロパティを設定できます:
- 名前(Shader内のプロパティ名)
- 種類(
Int
・Float
・FloatArray
・Texture
・Color
) - 値(選んだ種類に応じて変化)
💡
MaterialPropertyBlock
を使うため、Rendererを持つGameObjectにのみ有効です。
💡 プロパティの名前を知るにはシェーダーのソースコードを確認する必要があります。(慣習的に_
で始まる場合が多い。)Properties { _Color ("Color", Color) = (1,1,1,1) _MainTex ("Albedo", 2D) = "white" {} }
- 手動で一括適用
Unityのメニューから、登録された全オブジェクトにプロパティを一括適用できます:
MyTools > MaterialPropertyApplier.Apply
適用を解除することもできます:
MyTools > MaterialPropertyApplier.Clear
💡 Playモード終了時には適用したプロパティは解除されます。(これは
MaterialPropertyBlock
の特性によるものです。)