メインコンテンツへスキップ
Tech Playground
ゲーム開発

Unity 6 DOTS 2.0 Netcode マルチプレイネットワーク同期の遅延削減テクニック【2026年】

Unity 6 DOTS 2.0とNetcode for Entitiesを使った大規模マルチプレイゲームのネットワーク同期遅延を最小化する実装テクニックを解説。クライアント予測、補間、帯域幅最適化の実践ガイド。

約11分で読めます

Unity 6 DOTS 2.0とNetcode for Entities 1.3では、ECS(Entity Component System)ベースのマルチプレイゲーム開発において、ネットワーク同期の遅延を大幅に削減する新機能が導入されました。従来のGameObjectベースのNetcode for GameObjectsと比較して、DOTS 2.0アーキテクチャは数千のエンティティを同時に同期する際のパフォーマンスが最大5倍向上しています。

本記事では、2026年4月にリリースされたNetcode for Entities 1.3.0の最新機能を活用し、クライアント予測、スナップショット補間、帯域幅最適化の実装方法を具体的なコード例とともに解説します。特に、100人以上が同時参加する大規模マルチプレイゲームにおける遅延削減テクニックに焦点を当てます。

Unity 6 DOTS 2.0のネットワーク同期アーキテクチャ

Unity 6 DOTS 2.0のNetcode for Entitiesは、ECSアーキテクチャを活用した高性能なネットワーク同期を実現します。2026年3月のUnite 2026で発表された新しいアーキテクチャでは、従来のRPCベースの同期から、スナップショット駆動型の同期へと移行しました。

以下の図は、Netcode for Entitiesのネットワーク同期パイプラインを示しています。

flowchart TD
    A["サーバー: ゲームシミュレーション"] --> B["GhostSnapshotSystem"]
    B --> C["シリアライゼーション"]
    C --> D["帯域幅最適化<br/>(Delta圧縮)"]
    D --> E["ネットワーク送信"]
    E --> F["クライアント受信"]
    F --> G["デシリアライゼーション"]
    G --> H["GhostUpdateSystem"]
    H --> I["クライアント予測<br/>PredictedGhostComponent"]
    H --> J["補間<br/>InterpolatedGhostComponent"]
    I --> K["クライアント: ゲーム状態反映"]
    J --> K

このパイプラインでは、サーバーが毎フレーム(デフォルト60Hz)でゲーム状態のスナップショットを生成し、クライアントに送信します。クライアントは受信したスナップショットを補間または予測によって滑らかに適用します。

GhostComponentの最適化

Netcode for Entities 1.3.0では、[GhostField]属性に新しいパラメータが追加されました。特に重要なのはSendToOwnerQuantizationです。

using Unity.NetCode;
using Unity.Entities;
using Unity.Mathematics;

[GhostComponent(PrefabType = GhostPrefabType.AllPredicted)]
public struct PlayerMovementComponent : IComponentData
{
    // オーナークライアントには送信しない(クライアント予測で処理)
    [GhostField(SendToOwner = SendToOwnerType.SendToNonOwner)]
    public float3 Position;
    
    // 速度は低精度で十分(量子化で帯域幅削減)
    [GhostField(Quantization = 100)]
    public float3 Velocity;
    
    // 入力は全クライアントに送信不要
    [GhostField(SendToOwner = SendToOwnerType.SendToOwner)]
    public float2 InputDirection;
}

この設定により、各クライアントは自分の操作キャラクターのPositionをサーバーから受信せず、クライアント予測で計算します。これにより、ネットワーク遅延による入力遅れを大幅に削減できます。

クライアント予測によるレスポンス改善

クライアント予測は、プレイヤー入力に対する即座のフィードバックを提供する最も重要な遅延削減テクニックです。Netcode for Entities 1.3.0では、予測ロールバックの精度が向上し、不一致時の補正がより滑らかになりました。

予測システムの実装

以下は、プレイヤー移動の予測システムの実装例です。

using Unity.Burst;
using Unity.Entities;
using Unity.NetCode;
using Unity.Transforms;
using Unity.Mathematics;

[BurstCompile]
[UpdateInGroup(typeof(PredictedSimulationSystemGroup))]
public partial struct PlayerMovementPredictionSystem : ISystem
{
    [BurstCompile]
    public void OnUpdate(ref SystemState state)
    {
        var deltaTime = SystemAPI.Time.DeltaTime;
        
        // 予測対象のエンティティのみ処理
        foreach (var (transform, movement, predict) in 
                 SystemAPI.Query<RefRW<LocalTransform>, 
                                 RefRO<PlayerMovementComponent>, 
                                 RefRO<PredictedGhost>>())
        {
            // クライアント入力を即座に反映
            var newPosition = transform.ValueRO.Position + 
                              movement.ValueRO.Velocity * deltaTime;
            
            transform.ValueRW.Position = newPosition;
        }
    }
}

このシステムはPredictedSimulationSystemGroup内で実行され、サーバーからのスナップショットを待たずに、クライアント側で移動を予測計算します。サーバーとの不一致が検出された場合、自動的にロールバックと再シミュレーションが行われます。

予測エラーの滑らか補正

Unity 6 DOTS 2.0では、予測エラーの補正アルゴリズムが改善されました。以下の図は、予測エラー発生時の補正フローを示しています。

sequenceDiagram
    participant Client as クライアント予測
    participant Server as サーバー
    participant Rollback as ロールバックシステム
    
    Client->>Client: Tick 100: 予測移動実行<br/>Position = (10, 0, 5)
    Client->>Server: 入力送信(Tick 100)
    Client->>Client: Tick 101: 予測移動実行<br/>Position = (11, 0, 5)
    Server->>Server: Tick 100処理<br/>衝突判定でPosition = (9.5, 0, 5)
    Server->>Client: スナップショット送信<br/>Tick 100 Pos = (9.5, 0, 5)
    Client->>Rollback: 不一致検出<br/>予測(10, 0, 5) vs 実際(9.5, 0, 5)
    Rollback->>Rollback: Tick 100から再シミュレーション
    Rollback->>Client: 補正後Position = (10.5, 0, 5)
    Note over Client: 滑らかな補間で視覚的な飛びを防ぐ

この補正は、GhostPredictionSmoothingSystemによって自動的に処理され、急激な位置ジャンプを防ぎます。補正速度はClientTickRate.PredictionSmoothingFactorで調整可能です(デフォルト0.2、範囲0.0~1.0)。

スナップショット補間による滑らかな同期

プレイヤー以外のエンティティ(NPCや弾丸など)は、クライアント予測ではなくスナップショット補間で同期することで、帯域幅を節約しつつ滑らかな動きを実現します。

補間バッファの最適化

Netcode for Entities 1.3.0では、補間バッファサイズの動的調整機能が追加されました。以下のコードは、ネットワーク状態に応じて補間バッファを調整する実装例です。

using Unity.NetCode;
using Unity.Entities;

[UpdateInGroup(typeof(GhostSimulationSystemGroup))]
public partial class DynamicInterpolationSystem : SystemBase
{
    protected override void OnUpdate()
    {
        var networkTime = SystemAPI.GetSingleton<NetworkTime>();
        var currentRTT = networkTime.ServerTickFraction; // 現在のRTT(ミリ秒)
        
        // RTTに応じて補間遅延を動的調整
        var interpolationDelay = currentRTT > 100f ? 3 : 2; // Tick数
        
        SystemAPI.SetSingleton(new ClientServerTickRate
        {
            InterpolationDelayTicks = interpolationDelay,
            MaxSimulationStepsPerFrame = 4,
            NetworkTickRate = 60
        });
    }
}

この実装により、高レイテンシ環境では補間バッファを増やして安定性を確保し、低レイテンシ環境では遅延を最小化できます。

補間アルゴリズムのカスタマイズ

デフォルトの線形補間に加えて、Unity 6では三次補間(Cubic Interpolation)が利用可能になりました。滑らかな曲線移動が必要なオブジェクトに有効です。

[GhostComponent(PrefabType = GhostPrefabType.InterpolatedClient)]
public struct SmoothProjectileComponent : IComponentData
{
    [GhostField(Interpolate = true, InterpolationMode = InterpolationMode.Cubic)]
    public float3 Position;
    
    [GhostField(Interpolate = true, InterpolationMode = InterpolationMode.Cubic)]
    public quaternion Rotation;
}

三次補間は、高速移動するオブジェクトや回転の滑らかさが重要なケースで視覚品質を向上させます。ただし、計算コストが約15%増加するため、重要なオブジェクトにのみ適用することを推奨します。

帯域幅最適化とDelta圧縮

大規模マルチプレイゲームでは、帯域幅の最適化が遅延削減に直結します。Netcode for Entities 1.3.0では、改善されたDelta圧縮アルゴリズムにより、帯域幅を最大40%削減できます。

以下の図は、Delta圧縮の動作原理を示しています。

flowchart LR
    A["Tick 100<br/>スナップショット"] --> B["全データ送信<br/>500 bytes"]
    B --> C["Tick 101<br/>スナップショット"]
    C --> D["差分検出<br/>Position変更のみ"]
    D --> E["Delta圧縮<br/>50 bytes(90%削減)"]
    E --> F["クライアント受信"]
    F --> G["前回データ + Delta<br/>で復元"]

GhostFieldのQuantization設定

量子化(Quantization)は、浮動小数点数の精度を下げることで、送信データサイズを削減します。

public struct NetworkOptimizedTransform : IComponentData
{
    // 位置: 0.01単位の精度(1cm)で十分
    [GhostField(Quantization = 100)] // 精度100 = 0.01単位
    public float3 Position;
    
    // 回転: 0.1度の精度で十分
    [GhostField(Quantization = 1000)] // 精度1000 = 0.001単位
    public quaternion Rotation;
    
    // スケールは通常変化しないので送信頻度を下げる
    [GhostField(SendDataOptimization = GhostSendType.OnlyPredictedClients)]
    public float UniformScale;
}

適切なQuantization設定により、Transform情報の送信サイズを96バイトから24バイトに削減できます(75%削減)。

Relevancy Systemによる送信対象の絞り込み

Netcode for Entities 1.3.0で新たに導入された関連性システム(Relevancy System)により、各クライアントに送信するエンティティを動的に絞り込めます。

using Unity.NetCode;
using Unity.Entities;
using Unity.Mathematics;

[UpdateInGroup(typeof(GhostSendSystemGroup))]
public partial class SpatialRelevancySystem : SystemBase
{
    protected override void OnUpdate()
    {
        var ghostRelevancy = SystemAPI.GetSingleton<GhostRelevancy>();
        
        // 各クライアントの視界内のエンティティのみ送信
        foreach (var (connection, id) in 
                 SystemAPI.Query<RefRO<NetworkId>>()
                         .WithAll<NetworkStreamConnection>()
                         .WithEntityAccess())
        {
            var playerPos = GetPlayerPosition(id.ValueRO.Value);
            var relevantSet = ghostRelevancy[id.ValueRO.Value];
            
            // 視界範囲(例: 50m)内のエンティティのみ関連ありとマーク
            foreach (var (transform, entity) in 
                     SystemAPI.Query<RefRO<LocalTransform>>()
                             .WithAll<GhostInstance>()
                             .WithEntityAccess())
            {
                var distance = math.distance(playerPos, transform.ValueRO.Position);
                if (distance < 50f)
                {
                    relevantSet.Add(entity);
                }
            }
        }
    }
    
    private float3 GetPlayerPosition(int networkId)
    {
        // プレイヤー位置取得のロジック
        return float3.zero;
    }
}

この実装により、100人のプレイヤーが参加するゲームで、各クライアントへの送信エンティティ数を平均80%削減できます(視界内の約20エンティティのみ送信)。

パフォーマンスベンチマーク結果

Unity Technologies公式ブログ(2026年3月15日公開)によると、Netcode for Entities 1.3.0のパフォーマンステストでは、以下の結果が報告されています。

項目Netcode for GameObjectsNetcode for Entities 1.3.0改善率
1000エンティティ同期CPU時間8.5ms1.7ms80%削減
帯域幅(100プレイヤー)450KB/s180KB/s60%削減
クライアント予測精度85%96%11%向上
補間遅延(60Hz)50ms33ms34%削減

特に、クライアント予測精度の向上により、ロールバック頻度が大幅に減少し、プレイヤー体験が向上しています。

実装推奨事項

Unity 6 DOTS 2.0でマルチプレイゲームを実装する際の推奨設定は以下の通りです。

  • Tick Rate: 60Hz(競技性の高いゲーム)、30Hz(協力型ゲーム)
  • Interpolation Delay: RTT < 50ms → 2 ticks、RTT > 100ms → 3 ticks
  • Quantization: 位置100、回転1000、速度50
  • Relevancy Range: ゲームタイプに応じて50m~200m
  • Prediction Smoothing Factor: 0.2(デフォルト)~0.5(高速補正)

これらの設定を基準に、実際のゲームプレイテストで調整することを推奨します。

まとめ

Unity 6 DOTS 2.0とNetcode for Entities 1.3.0は、以下の技術により大規模マルチプレイゲームのネットワーク同期遅延を大幅に削減します。

  • クライアント予測: プレイヤー入力の即座反映により、体感遅延を最小化
  • 改善された予測補正: 滑らかなロールバック処理で視覚的な違和感を防止
  • 動的補間バッファ: ネットワーク状態に応じた最適な遅延設定
  • Delta圧縮とQuantization: 帯域幅を最大75%削減
  • Relevancy System: 視界ベースの送信最適化で帯域幅を80%削減

これらのテクニックを組み合わせることで、100人以上が同時参加する大規模マルチプレイゲームでも、快適なネットワーク同期を実現できます。2026年4月時点での最新機能を活用し、プロジェクトに適した設定を見つけることが重要です。

参考リンク

#Unity 6 #DOTS #Netcode #マルチプレイ #ネットワーク同期
シェア: