---
title: プレイヤーループのカスタマイズ
product: Unity Editor
version: '6000.0'
latest_version: '7000.0'
status: This page documents version 6000.0. The latest version is 7000.0.
canonical: https://docs.unity.com/ja-jp/engine/6000.0/manual/scripting/object-oriented-development/managing-update-order/player-loop-customizing
latest_url: https://docs.unity.com/ja-jp/engine/7000.0/manual/scripting/object-oriented-development/managing-update-order/player-loop-customizing.md
generated_at: 2026-11-14T04:46:47.736Z
locale: ja-jp
---

# プレイヤーループのカスタマイズ

> プレイヤーループをカスタマイズして、ループの各イテレーションで Unity がシステムを更新する順序を変更します。

Unity ランタイムアプリケーションは、プレイヤーループと呼ばれる連続ループで実行されます。プレイヤーループの各イテレーション中に、Unity はレンダリング、物理演算シミュレーション、入力処理などのタスクを実行するためにさまざまなシステムを呼び出します。

プレイヤーループ中に更新されたさまざまなシステムとサブシステムは、定義されたデフォルトの順序で呼び出されます。この順序は、[`PlayerLoop`](/engine/6000.0/script-reference/unityengine/lowlevel/playerloop.md) API の静的メソッドを使用して表示およびカスタマイズできます。デフォルトまたは現在のプレイヤーループを取得して、独自のカスタムプレイヤーループシステムを挿入したり、既存のプレイヤーループシステムを削除、並べ替え、または置き換えたりすることができます。

プレイヤーループをカスタマイズする必要がある理由はいくつかあります。

* カスタム[更新マネージャー](/engine/6000.0/manual/scripting/object-oriented-development/managing-update-order/events-per-frame-optimization.md)の一部として独自のマネージ更新を作成すると、Unity のネイティブイベント機能の代わりによりパフォーマンスの高い機能を使用できます。詳細については、Unity ブログの「[10000 更新コール](https://unity.com/blog/engine-platform/10000-update-calls)」を参照してください。
* プレイヤー ループを特定のプラットフォームに合わせて最適化したい場合があります。例えば、モバイル ゲームの物理演算、AI、XR のアップデートを削除する場合などです。
* 編集モードまたは再生モードで更新ループを視覚化して、デバッグのヘルプに使用できます。

## プレイヤーループへのアクセス##accessing-the-player-loop

プレイヤーループは、一連のネストされたプレイヤーループシステムで構成され、それぞれが[`PlayerLoopSystem`](/engine/6000.0/script-reference/unityengine/lowlevel/playerloopsystem.md)構造体です。ルートまたは最も外側のプレイヤー ループ システムは、プレイヤー ループ全体を表し、その下に他のプレイヤー ループ システムがネスト状になっています。

この場合のプレイヤーループシステムとは、プレイヤーループ中に更新が必要なものを抽象化したにすぎません。デフォルトシステムは、オーディオや入力などのネイティブ Unity システムを表しますが、C# コードから独自のカスタムシステムを作成することもできます。

Unity のデフォルト プレイヤー ループにアクセスするには、[`PlayerLoop.GetDefaultPlayerLoop` を](/engine/6000.0/script-reference/unityengine/lowlevel/playerloop/getdefaultplayerloop.md)使用します。現在エフェクト中のプレイヤー ループにアクセスするには、[`PlayerLoop.GetCurrentPlayerLoop` を](/engine/6000.0/script-reference/unityengine/lowlevel/playerloop/getcurrentplayerloop.md)使用します。[`PlayerLoop.SetPlayerLoop`](/engine/6000.0/script-reference/unityengine/lowlevel/playerloop/setplayerloop.md) で新しいカスタムプレイヤーループを適用しない限り、デフォルトと現在のプレイヤーループは同じになります。

プレイヤーループ内の各システムには、それを識別する [`PlayerLoopSystem.type`](/engine/6000.0/script-reference/unityengine/lowlevel/playerloopsystem/type.md) プロパティがあります。プレイヤーループシステム構造体を再帰的に反復し、各 `type` プロパティの[`Name`](https://learn.microsoft.com/en-us/dotnet/api/system.reflection.memberinfo.name?view=net-9.0#system-reflection-memberinfo-name)を出力して、プレイヤーループ構造体をコンソールにディスプレイできます。以下の例に示すように、`type` プロパティを使用して、追加、削除、または置換するプレイヤーループサブシステムを特定することもできます。デフォルト システムに有効なタイプは、`UnityEngine.PlayerLoop` 名前空間で使用できます。

API リファレンス[`PlayerLoop.GetDefaultPlayerLoop`](/engine/6000.0/script-reference/unityengine/lowlevel/playerloop/getdefaultplayerloop.md)には、デフォルトのプレイヤーループを取得し、ネストされたプレイヤーループシステムを反復し、`type`プロパティの`Name`を出力する方法の例が含まれています。コードは以下のコンソール出力を生成します。

```text
ルートノード
	TimeUpdate
		WaitForLastPresentationAndUpdateTime
	初期化
		ProfilerStartFrame
		UpdateCameraMotionVectors
		DirectorSampleTime
		AsyncUploadTimeSlicedUpdate
		SynchronizeInputs
		SynchronizeState
		XREarlyUpdate
	EarlyUpdate
		PollPlayerConnection
		GpuTimestamp
		AnalyticsCoreStatsUpdate
		UnityWebRequestUpdate
		ExecuteMainThreadJobs
		ProcessMouseInWindow
		ClearIntermediateRenderers
		ClearLines
		PresentBeforeUpdate
		ResetFrameStatsAfterPresent
		UpdateAsyncInstantiate
		UpdateAsyncReadbackManager
		UpdateStreamingManager
		UpdateTextureStreamingManager
		UpdatePreloading
		UpdateContentLoading
		RendererNotifyInvisible
		PlayerCleanupCachedData
		UpdateMainGameViewRect
		UpdateCanvasRectTransform
		XRUpdate
		UpdateInputManager
		ProcessRemoteInput
		ScriptRunDelayedStartupFrame
		UpdateKinect
		DeliverIosPlatformEvents
		ARCoreUpdate
		DispatchEventQueueEvents
		Physics2DEarlyUpdate
		PhysicsResetInterpolatedTransformPosition
		SpriteAtlasManagerUpdate
		PerformanceAnalyticsUpdate
	FixedUpdate
		ClearLines
		NewInputFixedUpdate
		DirectorFixedSampleTime
		AudioFixedUpdate
		ScriptRunBehaviourFixedUpdate
		DirectorFixedUpdate
		LegacyFixedAnimationUpdate
		XRFixedUpdate
		PhysicsFixedUpdate
		Physics2DFixedUpdate
		PhysicsClothFixedUpdate
		DirectorFixedUpdatePostPhysics
		ScriptRunDelayedFixedFrameRate
	PreUpdate
		PhysicsUpdate
		Physics2DUpdate
		PhysicsClothUpdate
		CheckTexFieldInput
		IMGUISendQueuedEvents
		NewInputUpdate
		InputForUIUpdate
		SendMouseEvents
		AIUpdate
		WindUpdate
		UpdateVideo
	Update
		ScriptRunBehaviourUpdate
		ScriptRunDelayedDynamicFrameRate
		ScriptRunDelayedTasks
		DirectorUpdate
	PreLateUpdate
		AIUpdatePostScript
		DirectorUpdateAnimationBegin
		LegacyAnimationUpdate
		DirectorUpdateAnimationEnd
		DirectorDeferredEvaluate
		AccessibilityUpdate
		UIElementsUpdatePanels
		EndGraphicsJobsAfterScriptUpdate
		ConstraintManagerUpdate
		ParticleSystemBeginUpdateAll
		Physics2DLateUpdate
		PhysicsLateUpdate
		ScriptRunBehaviourLateUpdate
	PostLateUpdate
		PlayerSendFrameStarted
		DirectorLateUpdate
		ScriptRunDelayedDynamicFrameRate
		PhysicsSkinnedClothBeginUpdate
		UpdateRectTransform
		PlayerUpdateCanvases
		UIElementsRepaintPanels
		UpdateAudio
		VFXUpdate
		ParticleSystemEndUpdateAll
		EndGraphicsJobsAfterScriptLateUpdate
		UpdateCustomRenderTextures
		XRPostLateUpdate
		UpdateAllRenderers
		UpdateLightProbeProxyVolumes
		EnlightenRuntimeUpdate
		UpdateAllSkinnedMeshes
		ProcessWebSendMessages
		SortingGroupsUpdate
		UpdateVideoTextures
		UpdateVideo
		DirectorRenderImage
		PlayerEmitCanvasGeometry
		UIElementsRenderBatchModeOffscreen
		PhysicsSkinnedClothFinishUpdate
		FinishFrameRendering
		BatchModeUpdate
		PlayerSendFrameComplete
		UpdateCaptureScreenshot
		PresentAfterDraw
		ClearImmediateRenderers
		PlayerSendFramePostPresent
		UpdateResolution
		InputEndFrame
		TriggerEndOfFrameCallbacks
		GUIClearEvents
		ShaderHandleErrors
		ResetInputAxis
		ThreadedLoadingDebug
		ProfilerSynchronizeStats
		MemoryFrameMaintenance
		ExecuteGameCenterCallbacks
		XRPreEndFrame
		ProfilerEndFrame
		GraphicsWarmupPreloadedShaders
		ObjectDispatcherPostLateUpdate
```

## デフォルトプレイヤーループへのカスタム更新の挿入##insert-a-custom-update-into-the-default-player-loop

プレイヤーループをカスタマイズする推奨かつリスクの低い方法は、カスタムプレイヤーループシステムをデフォルトのプレイヤーループに挿入することです。こうすることで、Unityのビルトイン システムを停止することなく、独自のカスタム更新ロジックを追加できます。

[`PlayerLoop.SetPlayerLoop`](/engine/6000.0/script-reference/unityengine/lowlevel/playerloop/setplayerloop.md) API リファレンスのコード例は、特定の時点でカスタムプレイヤーループシステムをデフォルトプレイヤーループに挿入する方法を示しています。その場合、`CustomUpdate` メソッドの動作は `InsertSystem` クラスで定義されます。ただし、以下の小さな変更によって、`CustomUpdate`を MonoBehaviour スクリプトがサブスクライブできるイベントにしたり、独自の更新ロジックを提供したりできます。

* イベントを `InsertSystem` クラスの public 静的フィールドとして宣言します。

```lang-cs
public static event Action AddCustomUpdate;
```

* このイベントを呼び出すように `CustomUpdate` メソッドの定義を変更します。

```lang-cs
private static void CustomUpdate() => AddCustomUpdate?.Invoke();
```

その後、任意の MonoBehaviour スクリプトから次のようにカスタム更新をサブスクライブできます。

```cs
using UnityEngine;

public class CustomUpdateFromEvent :MonoBehaviour
{
    private void OnEnable()
    {
        InsertSystem.AddCustomUpdate += MyCustomUpdate;
    }

    private void Update()
    {
        Debug.Log("Update");
    }

    private void LateUpdate()
    {
        Debug.Log("Late Update");
    }

    private void OnDisable()
    {
        InsertSystem.AddCustomUpdate -= MyCustomUpdate;
    }

    private void MyCustomUpdate()
    {
        Debug.Log("Custom update from an event that your MonoBehaviour scripts can subscribe to.");
    }
}
```

> **Note:**
>
> [`PlayerLoop.SetPlayerLoop`](/engine/6000.0/script-reference/unityengine/lowlevel/playerloop/setplayerloop.md) にパラメーターとして渡すプレイヤーループシステムは、現在のプレイヤーループを上書きします。したがって、このメソッドに渡すループには、置き換えないシステムを含め、保持するすべてのシステムが含まれていることを確認してください。新しいプレイヤーループシステムをゼロから作成する場合は、保持するすべてのシステムを新しいループに明示的に追加する必要があります。

## プレイヤーループ内のデフォルトシステムを置き換える##replace-a-default-system-in-the-player-loop

以下の例では、プレイヤーループ内のデフォルトシステムをカスタム更新に置き換えます。この例では`PreUpdate.AIUpdate`システムを置き換えますが、[PlayerLoopSystem.type](/engine/6000.0/script-reference/unityengine/lowlevel/playerloopsystem/type.md) 識別子を指定することでプレイヤーループ内のすべてのシステムを置き換えることができます。デフォルト システムの有効タイプは、前のセクションで示したデフォルト プレイヤー ループを使用するか、`UnityEngine.PlayerLoop`名前空間から取得できます。

> **Important:**
>
> プレイヤーループでシステムを交換すると、そのシステムのデフォルト機能が削除されるため、意図しない結果になる可能性があります。このメソッドは、デフォルトの機能を独自のカスタムロジックに置き換えることが確実な場合にのみ、慎重に使用してください。

```cs
using UnityEngine.LowLevel;
using UnityEngine.PlayerLoop;
using UnityEngine;

// Replace an existing system in the Unity Player Loop with a custom update.

public class MyReplacementCustomUpdate { } // Empty class to use as a type identifier for the custom update

public class SystemReplacement
{
    //Run this method on runtime initialization
    [RuntimeInitializeOnLoadMethod]
    private static void AppStart()
    {
        // Retrieve the default Player loop system.デフォルトがすでに以前変更されている場合は、代わりに現在のループを取得します。
        var defaultSystems = PlayerLoop.GetDefaultPlayerLoop();
        // Create a custom update system to replace an existing one
        var customUpdate = new PlayerLoopSystem()
        {
            updateDelegate = CustomUpdate,
            type = typeof(MyReplacementCustomUpdate)
        };
        // Specify the system to replace as the type parameter, in this case PreUpdate.AIUpdate
        ReplaceSystem<PreUpdate.AIUpdate>(ref defaultSystems, customUpdate);
        PlayerLoop.SetPlayerLoop(defaultSystems);
    }

    // Custom update method that will be called in the Player Loop
    private 静的 void CustomUpdate()
    {
        Debug.Log("Custom update from a replacement system.");
    }

    //Recursively replace a system of type T with a replacement system in the Player Loop
    private static bool ReplaceSystem<T>(ref PlayerLoopSystem system, PlayerLoopSystem replacement)
    {
        if (system.type == typeof(T))
        {
            system = replacement;
            return true;
        }
        if (system.subSystemList != null)
        {
            for (var i = 0; i < system.subSystemList.Length; i++)
            {
                if (ReplaceSystem<T>(ref system.subSystemList[i], replacement))
                {
                    return true;
                }
            }
        }
        return false;
    }
}
```

## その他のリソースと例##additional-resources-and-examples

* 📚 **ドキュメント**: [イベント機能実行順序](/engine/6000.0/manual/scripting/object-oriented-development/managing-update-order/execution-order.md)
* API リファレンス
* 📚 **ドキュメント**: [10000 更新コール](https://unity.com/blog/engine-platform/10000-update-calls)
* Unity Discussions での👥 **コミュニティ**:[`LowLevel.PlayerLoop`トピック](https://discussions.unity.com/search?expanded=true\&q=LowLevel.PlayerLoop%20order%3Alatest_topic)
