YamaStudio.net

【Unity NGO】Tick Rate 30Hzに落とした理由——ソロ開発FPSの帯域と予測誤差の実測

公開日: 2026年10月12日 | カテゴリ: ゲーム開発 / Unity / C#

『VALOPEX STRIKE 2』のネット同期を詰めている最中に、「見た目の滑らかさ」と「実測の帯域」が噛み合わない局面に何度もぶつかりました。結論から書くと、サーバーTickは30Hz固定、クライアント描画は60〜144で予測+補間に落ち着いています。この記事は、60Hz同期を捨てたときのProfilerの数字と、捨てなかったら何が壊れたかを残す開発メモです。

Unity NGO向けネットワークプロファイラのモック。Tick Rate 30Hz、送信48KB/s、受信62KB/s、RTT 38msを表示
開発中ビルドで見ていた帯域のイメージ。敵8体+プレイヤー4人の屋内マップで、送信がおおよそ40〜55KB/sに収まった時点のメモ。

最初の失敗:Tickを描画フレームに引きずった

NGOのデフォルト感覚だと「Tickは高いほど正確」に見えます。私も最初、NetworkManager 側を60に寄せて「クライアントの144Hzに負けない同期」を狙いました。結果は次の通りです。

  • ホスト+3クライアントのLANでも、移動パケットの送信がすぐに100KB/s超
  • アニメーションIKのボーン同期を乗せた瞬間、Wi‑Fiクライアントでスタッタが常態化
  • 「撃ったのに当たらない」体感が、RTTより先に帯域飽和で増えた

FPSは「見た目のフレーム」と「権威あるシミュレーションの刻み」を分けないと、ソロ開発の回線予算を一瞬で食いつぶします。ここを混同していたのが最大のミスでした。

実測条件

項目内容
エンジンUnity 6 / Netcode for GameObjects
シーン屋内倉庫マップ、ナビメッシュあり
人数プレイヤー4+AI敵8(単純Chase)
同期対象位置・回転・照準Yaw、武器ステート、ヒットイベント
計測Unity Profiler Network + 自前のKB/sログ
回線同一LAN(有線)と、意図的に50ms遅延を挟んだ試験

30Hzにしたあとの数字

Tickを30に落とし、クライアント側は予測(移動)+スナップショット補間(他プレイヤー)に振り分けたあと、同じシーンでのおおよその値はこうなりました。

指標Tick 60時Tick 30時
送信帯域(ホスト目安)95〜130 KB/s40〜55 KB/s
受信帯域(クライアント)110〜150 KB/s55〜70 KB/s
ヒット判定の体感ズレ小さいが回線で破綻しやすい補間窓を調整すれば許容
Wi‑Fiクライアントのスタッタ頻発ほぼ消えた

「半分にしたら帯域も半分」に近い挙動でした。当たり前の話ですが、ボーンやIKを乗せる前にこの当たり前を数字で確認しておくべきでした。

サーバーTick 30Hzとクライアント予測・スナップショット補間の関係を示すタイムライン図
サーバーは30Hzで権威ある状態を進め、クライアントは入力予測で描画を先行させ、他者はスナップショットを補間する——この分離が今回の肝。

実装で効いた3つの判断

1. 位置は「高頻度・低精度」、ヒットは「イベント」

毎Tickでフルステートを流すのをやめ、移動は量子化した差分、ヒットはReliableイベントに分離しました。当たった/外れたの最終判断はサーバーだけが持ち、クライアントのトレーサーは演出です。

2. 補間遅延は「見た目のラグ」として明示的に買う

他プレイヤーの表示を100〜120ms遅らせる設定にしています。自分のエイムは予測で先行するので、クロスヘアの感覚は残ります。逆に補間を切ると、帯域が空いていても「カクつく他人」がストレスになりました。

3. TickとFixedUpdateを混同しない

物理はFixedUpdate 50Hz、ネットTickは30Hz、と意図的にずらしています。最初は「全部60に揃えれば楽」と思いましたが、揃えるコストが通信に出ます。ソロ開発では、揃えない前提でデバッグログを書く方が早いです。

30Hzで壊れたもの/壊れなかったもの

  • 壊れた:超至近距離のストレイフ撃ち合いで、見た目の銃口とヒットボックスが数フレームズレる。リコイルパターンの「見た目再現」をクライアント任せにしたら誤認が増えた
  • 壊れなかった:中〜遠距離のピーク撃ち、ドア開け瞬間のワンウェイ感、AI敵のChase。ここがゲームの主戦場なら30Hzで十分だった

VALOPEX STRIKE 2は「タクティカル寄りのテンポ」なので、CS直系の至近ストレイフ精度より、ピークとユーティリティの読み合いを優先しています。ジャンル前提がTick選定を決めた、と言ってよいです。

今の推奨パラメータ(個人開発メモ)

項目値理由
Server Tick30帯域と権威のバランス
Client 描画モニター依存同期とは分離
他者補間遅延100〜120msスタッタよりラグを買う
位置量子化1cm単位倉庫マップでは十分な精度
アニメIK同期間引き/ローカル再現生ボーン同期は禁止に近い

これから詰めること

次は「ヒットイベントの巻き戻し窓」をTick単位で何フレーム持つかです。30Hzだと1Tick=33msなので、巻き戻し3Tickでも約100ms。リコイル中の連射でこの窓が足りるか、実プレイのデモ録画と照合しながら決めます。前回のUnity開発記で書いたIK・UIの泥沼とセットで、ネット側も「見た目の正義」より「再現可能な数字」を優先する方針です。

ソロ開発のマルチプレイは、美しい同期より先に「回線が死なない同期」が必要でした。Tickを下げたのは後退ではなく、ジャンルに合わせた予算配分です。

← 記事一覧へ戻る