【Unity NGO】Tick Rate 30Hzに落とした理由——ソロ開発FPSの帯域と予測誤差の実測
公開日: 2026年10月12日 | カテゴリ: ゲーム開発 / Unity / C#
『VALOPEX STRIKE 2』のネット同期を詰めている最中に、「見た目の滑らかさ」と「実測の帯域」が噛み合わない局面に何度もぶつかりました。結論から書くと、サーバーTickは30Hz固定、クライアント描画は60〜144で予測+補間に落ち着いています。この記事は、60Hz同期を捨てたときのProfilerの数字と、捨てなかったら何が壊れたかを残す開発メモです。
最初の失敗: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/s | 40〜55 KB/s |
| 受信帯域(クライアント) | 110〜150 KB/s | 55〜70 KB/s |
| ヒット判定の体感ズレ | 小さいが回線で破綻しやすい | 補間窓を調整すれば許容 |
| Wi‑Fiクライアントのスタッタ | 頻発 | ほぼ消えた |
「半分にしたら帯域も半分」に近い挙動でした。当たり前の話ですが、ボーンやIKを乗せる前にこの当たり前を数字で確認しておくべきでした。
実装で効いた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 Tick | 30 | 帯域と権威のバランス |
| Client 描画 | モニター依存 | 同期とは分離 |
| 他者補間遅延 | 100〜120ms | スタッタよりラグを買う |
| 位置量子化 | 1cm単位 | 倉庫マップでは十分な精度 |
| アニメIK同期 | 間引き/ローカル再現 | 生ボーン同期は禁止に近い |
これから詰めること
次は「ヒットイベントの巻き戻し窓」をTick単位で何フレーム持つかです。30Hzだと1Tick=33msなので、巻き戻し3Tickでも約100ms。リコイル中の連射でこの窓が足りるか、実プレイのデモ録画と照合しながら決めます。前回のUnity開発記で書いたIK・UIの泥沼とセットで、ネット側も「見た目の正義」より「再現可能な数字」を優先する方針です。
ソロ開発のマルチプレイは、美しい同期より先に「回線が死なない同期」が必要でした。Tickを下げたのは後退ではなく、ジャンルに合わせた予算配分です。