はじめに
Unity × Playmaker でシミュレーションゲームを作っている中で、ふと「Next Frame Event」の挙動について改めて考える機会がありました。
Playmakerでループ処理やデータの一括処理を行う際、私はよく Next Frame Event を使ってステートを遷移させています。
理由はシンプルで、「1フレーム遅らせて処理することで、Playmakerの内部ループ制限に引っかからず安全に回せる」からです。
無限ループっぽい処理でも正常に動くので、「便利〜」程度の軽い気持ちで、あまり深く考えず常用していました。
結論
FINISHED を使った場合の方が「早く」見えることがあるのは、
- 即時遷移される(同一フレーム内で処理される)ため。
Next Frame Eventは明示的に1フレーム遅らせるため、次のステートの処理が次フレームにずれる。
解説
FINISHED の動作
Finish()メソッドが呼ばれると、Playmakerは 同一フレーム内で次のステートのOnEnter()を呼ぶことがある。- 条件:そのステート内に
Wait,NextFrameEvent,Coroutine,Invoke等がなければ、即座に遷移可能。
NextFrameEvent の動作
- このアクションは、「明示的に次のフレームでイベントを送る」。
- Unityの
yield return nullに相当し、1フレーム待ってからSendEventが発生。 - そのため、次のステートの
OnEnter()は1フレーム遅れる。
「遅くなる」シーンの例
例えば以下の2つのFSMを比べてみましょう。
◆ パターン1:FINISHEDのみ
plaintextコピーする編集するState A
└── CustomAction
└── Finish(); // 同フレーム内で State B に移動
State B
└── OnEnter() 即発火
◆ パターン2:Next Frame Event使用
plaintextコピーする編集するState A
└── CustomAction
└── Fsm.Event("NEXT_FRAME_EVENT"); // 実際に遷移するのは1フレーム後
State B
└── OnEnter() は次フレーム
この差によって、動きのキレが違ったり、処理のタイミングがズレたりします。
応用ポイント
- パフォーマンス的にFINISHEDが有利:1フレーム遅延を避けられる。
- ただし、処理が重なる場合はNextFrameで分割してあげると、見た目やパフォーマンスが安定する。
- 大量のオブジェクト処理をする際はあえてNextFrameを使うこともある。
補足
内部的に Playmaker のステート遷移は Fsm.EnterState() で処理され、Finish() は即座に Transition を解決するトリガーになります。一方、 NextFrameEvent は LateUpdate() などで再度キュー処理されるため、確実に次フレームにずれます。
まとめ
| 手法 | 遷移タイミング | 処理速度 |
|---|---|---|
FINISHED | 同一フレーム内で即遷移 | 早い |
NextFrameEvent | 次のフレームで遷移 | 1フレーム遅れる |
おわりに
Next Frame Event をやめて、代わりに普通に FINISHED を使ってループステートを遷移させてみたところ……
一瞬で100件が並ぶ!!
その結果、Playmakerは同一フレーム内でループ処理を回し、UIも即表示され、パフォーマンスもスッキリ改善。
1件ごとのプレハブ生成処理が Next Frame Event を挟むことで毎フレーム1件ずつ処理されている状態になっていました。
つまり、100件生成するのに100フレームかかっていたんです。
そりゃあ、表示がもっさりするわけだ……。
「1フレーム遅らせる」コストは侮れない
Next Frame Event は便利だけど、常にベストな選択肢とは限らないということを学びました。
ループスタック対策や安全性重視 → Next Frame Event
高速な一括処理が必要 → FINISHEDで即時遷移
この違いを理解した上で、使い分けることが大事ですね。

