Optimization Tips
パフォーマンスの最適化
インスタンス化のプールオブジェクト
PUNには、読み込まれたリソースからではなく、プールからオブジェクトをインスタンス化するオプションが備え付けられています。(稼働速度を上げるため、メモリ上に保管されています。)インスタンス化に関するドキュメントページのプレハブプールの使用を参照してください。
RPCターゲットをキャッシュ
ゲーム内で大量のRPCを使用するケースもあるでしょう。
ターゲットGameObjectのあらゆるコンポーネントはRPCを実装することができるので、PUNはリフレクションを使用して適切なメソッドを見つけます。
もちろん、コンポーネントが変更されない場合は、これにはコストも手間もかかり無駄になります。
デフォルトで、PUNはスクリプトのタイプごとにMethodInfoリストをキャッシュします。
GameObject上で潜在的なターゲットであるMonoBehavioursはキャッシュしません。
PhotonNetwork.UseRpcMonoBehaviourCache = true
を設定して、RPCのPhotonView毎のMonoBehavioursをキャッシュできます。
これにより呼び出すコンポーネントを検出する速度が上がります。
GameObject上のスクリプトが変更されたら、必要に応じてphotonView.RefreshRpcMonoBehaviourCache()
を呼び出しアップデートしてください。
ネットワークトラフィックの最適化
コンパクトなシリアル化
送信しているものとその方法を詳しく調べることで、トラフィックをかなり最適化できます。 これは、開発の後半で、多くの余分な手間をかけずに行うことができます。 最適化では通常どおり、最も頻繁に送信されるメッセージから始めます。
多くの場合、値とオブジェクトは、状態を共有するために必要な値よりも多くの値で送信されます。キャラクターがスケールできない場合、スケールを同期しないでください! キャラクターが横に傾かない場合、回転は単一のフロートになる可能性があります。実際には、精度を大幅に低下させることなく、1バイトでローテーションを行うことができます。 これは、非物理オブジェクトには適しています。
一般的に、 OnPhotonSerializeView
とRPCで何をするかを見てください。 OnPhotonSerializeView
ごとに可変量の値を送信できます。 多くの場合、コンパクトなバイト配列を送信する方が、多くのカスタム型を登録して送信するよりも効率的です。
多くの手間をかけずに手間を省くツールがあります。 Network Transform Sync パッケージをご覧ください。 最適化されたトラフィックで高度な変換同期を提供します。送信するものを単純化する場合のオプションとしてはTransform Crusher - Free があります。
シリアル化に役立つ別のライブラリは NetStackです。他にもさまざまな便利な機能が備わっています。
ネットワークカリングとインタレストグループ
かなりの帯域幅を節約するもう1つの手法は、「ネットワークカリング」です。Interest Groupsを御覧ください。
Other Tips
すぐに送信
発生したRPCとイベントは、photonView.RPC
またはPhotonNetwork.RaiseEvent
を呼び出した瞬間には送信されません。
PhotonNetwork.LeaveRoom
、PhotonNetwork.SetMasterClient
、SetProperties
のようなオペレーションリクエストの場合も同じです。
代わりに、定期的なルーチンが PhotonHandler
によって呼び出されるまでキューに入れられます(頻度は PhotonNetwork.SendRate
を使用して設定されます)。
これにより、メッセージがより少ないパッケージに集約されてトラフィックのオーバーヘッドが回避されますが、多少の可変遅延が発生します。
この遅延を回避し、RPCまたはイベントをすぐに送信するには、次の行で PhotonNetwork.SendAllOutgoingCommands()
を呼び出します。
これは、ゲームがこれらのメッセージのタイミングに依存している場合に意味があります。例:
- タイミングの良い競争力のある雑学やクイズゲーム。早いほど良いです。
- 相手があなたの番を待っている。
ただし、メッセージの送信など、これには他のユースケースがあります。
- 切断する前
- ルームを出る前
- アプリを終了する前(
OnApplicationQuit
内) - アプリがバックグラウンドに移動するか、フォーカスを失う前(
OnApplicationPause
内またはOnApplicationFocus
内)
これらの場合、次のことを知っておく必要があります。
OnApplicationQuit
はすべてのプラットフォーム、たとえばAndroidで呼び出されるわけではありません。アプリケーションがシステムによって終了された場合、これは呼び出されません。
代わりにOnApplicationPause
を使用できます。- 通常、パッケージの平均損失は1.2%です。
信頼性のある送信を行った場合でも、再試行が必要になった場合にクライアントが応答しなくなったり、切断されたり、ルームに参加しなくなったりするため、送信したものが送信先に到着する保証はありません。 - これらの場合に送信されるメッセージは、クライアントが複数のフラグメントを送信するのに十分な時間がないため、1つのパッケージに収まるように比較的小さくする必要があります。
Time.timeScale == 0
中にPUNを一時停止しないでください
Time.timeScale
がゼロまたは低い場合でも、受信したメッセージをPUNでディスパッチできるようにするには、 PhotonNetwork.MinimalTimeScaleToDispatchInFixedUpdate
を Time.timeScale
以上の値に設定します。
デフォルトでは、-1に設定されます。これは、 Time.timeScale
が0に等しい場合、受信したイベント(RPCを含む)または操作のレスポンスが処理されないことを意味します(コールバックも操作も実行を終了できません)。