カスタム更新マネージャーの使用
更新マネージャーを作成して、フレームごとの更新を多数処理します。
読み終わるまでの所要時間 9 分最終更新 3日前
UpdateFixedUpdateLateUpdate適切なコールバックを必要とするプロジェクト内のすべての MonoBehaviour インスタンスに適切なコールバックを追加するのは便利ですが、コールバックの数が増えると非効率的になります。ネイティブコードからマネージコードコールバックを呼び出すと、小さいながらも重大なオーバーヘッドが発生します。これは、以下の結果につながります。
- 大量の コールバックを呼び出すときのフレーム時間が低下します。
Update - プレハブ内の各コンポーネントで コールバックと
Awakeコールバックを呼び出すことによるパフォーマンスのオーバーヘッドが原因で、多数の MonoBehaviour を含むプレハブをインスタンス化するときに、インスタンス化時間が低下しました。OnEnable
これらの問題を回避するには、ビルトインコールバックに依存する代わりに、グローバルカスタム更新マネージャのシングルトンインスタンスを作成し、MonoBehaviour スクリプトまたは標準の C# オブジェクトにサブスクライブさせます。このようにすると、更新マネージャーシングルトンは、、、およびその他のコールバックを、それらにサブスクライブしているすべてのオブジェクトに分散することができ、すべての更新コードはマネージレイヤーに留まります。これには、実行する操作がないときに、コードがコールバックからサブスクライブ解除できるようになるため、各フレームで呼び出す必要がある関数の数が減るという利点もあります。
UpdateLateUpdateカスタム更新マネージャを使用する場合
カスタム更新マネージャーは、フレームごとの更新コールバックを持つ MonoBehaviour インスタンスの数が数百または数千に達したときに便利です。
実行頻度の低いコールバックを排除することで、パフォーマンスを大幅に向上させることができます。以下の例を考えてみましょう。
void Update() { if(!someVeryRareCondition) { return; }// … some operation …}
プロジェクトにこのようなコールバックを持つ MonoBehaviour が多数ある場合、 コールバックの実行に消費される時間のかなりの部分が、MonoBehaviour 実行のネイティブコードドメインとマネージコードドメインの切り替えに費やされ、その後すぐに終了します。これらのクラスが、 が true の間だけグローバル更新マネージャーにサブスクライブし、その後はサブスクライブ解除すると、コードドメインの切り替えとまれな状態の評価の両方に費やす時間が短縮されます。
UpdateUpdatesomeVeryRareConditionカスタム更新マネージャの例
カスタム更新マネージャーを実装するには、最初に Cスクリプトを作成し、以下のようにインターフェースフェースを定義します。
public interface IUpdatable{ void CustomUpdate(float deltaTime);}
次に、更新マネージャーシングルトン用の MonoBehaviour スクリプトを作成できます。更新マネージャーはビルトインの コールバックを実装します。その後、他の MonoBehaviour スクリプトコンポーネントは、この更新マネージャーに直接するのではなく、この更新マネージャーにサブスクライブできます。
UpdateUpdate// Singleton update manager. Attach to a GameObject in your scene.using System.Collections.Generic;using UnityEngine;public class UpdateManager :MonoBehaviour{ private 静的 UpdateManager _instance; public static UpdateManager Instance => _instance; private readonly リスト<IUpdatable> updatables = new リスト<IUpdatable>(); void Awake() { if (_instance == null) _instance = this; else Destroy(gameObject); } public void Register(IUpdatable updatable) { if (!updatables.Contains(updatable)) updatables.Add(updatable); } public void Unregister(IUpdatable updatable) { updatables.Remove(updatable); } void Update() { float deltaTime = Time.deltaTime; // Optionally: for performance, iterate backwards if you allow removal during iteration Foreach (更新可能な変数) { updatable.CustomUpdate(deltaTime); } }}
最後に、MonoBehaviour スクリプトコンポーネントを作成し、enable 時に更新マネージャーインスタンスに登録し、使用不可 時に登録解除します。以下の例では、カスタム更新コールバックを使用して親ゲームオブジェクトを移動しています。
// Script component. Attach to a GameObject in your scene to move it on each custom update.using UnityEngine;public class MyMovingObject :MonoBehaviour、IUpdatable{ void OnEnable() { UpdateManager.Instance.Register(this); } void OnDisable() { if (UpdateManager.Instance != null) UpdateManager.Instance.Unregister(this); } public void CustomUpdate(float deltaTime) { // Your update logic here transform.position += Vector3.right * deltaTime; }}
追加リソース
- 📚 ドキュメント: イベント機能実行順序
- 📚 ドキュメント:イベント機能
- 📚 ドキュメント: 10000 更新コール