プレイヤー
概要
Player
(Player
スクリプト、Player
プレハブ) はゲーム内で接続された仲間を表し、ビジュアルはありません。プレイヤーは共通のメタデータ - ユーザーID、ニックネーム、選択したキャラクター、その他 Agent
(ゲーム世界で生成されるビジュアル表現) がリスポーンしても生き残るべきデータにアクセスすることができます。
**Agent** (
Agentスクリプト、
AgentBase プレハブ、およびその亜種) は、プレイヤーが操作するゲーム内のキャラクターを表します。
GameplayMode によって生成され、
Healthや
Weapons` などのコンポーネントを持っています。このキャラクターは必要に応じてスポーン、デスポーンされます。
次の図は、コンポーネント階層を実行のウォーターフォールとして示しています。
入力処理
次の図は、入力の処理とアクションの実行を表しています。
Notes:
Frame
: Unity のレンダリングフレーム番号、Tick
: Fusion の固定更新ティック数- 各フレームの開始時に、デバイスからの入力を
BeforeUpdate()
で収集し、Render Input
データ構造に書き込みます(入力権限のみ実行)。 - 同じ入力は
Cached Input
にも蓄積されます (たとえば、ルックローテーションデルタ) - 累積された差分時間が次の固定ティックをシミュレートするのに十分な大きさである場合 (フレーム 103)
NetworkEvents.OnInput()
コールバックを通じてCached Input
がポーリングされ、消費されます。- 最新の
Render Input
は既に蓄積されており、次のFixedUpdateNetwork()
で処理されるため、クリアする必要があり、二度適用されません (FixedUpdateNetwork()
とRender()
から) - プレイヤーの入力は
BeforeTick()
で Fusion から読み込まれ、Fixed Input
に格納されます (入力と状態の権限で実行されます) - 他のスクリプトで呼ばれる
FixedUpdateNetwork()
はFixed Input
を使ってゲームプレイのアクションを生成します。
- 他のスクリプトで呼ばれる
Render()
はRender Input
を使用してゲームプレイアクションを生成します。(動きを予測したレンダリング、射撃は FUN からのみ行われます。)
- 累積された差分時間が次の固定ティックをシミュレートするのに十分でない場合 (フレーム 101, 102)
- 他のスクリプトで呼ばれた
Render()
はRender Input
とCached Input
を使ってゲームプレイアクションを生成します (予測された動きをレンダリング、回転を見る)。
- 他のスクリプトで呼ばれた
この図は簡易版であり、すべてのエッジケースをカバーしているわけではありません。詳細については、ドキュメントを参照してください。
ルックローテーションスムージング
Fusion BRには、どのような条件下でもスムーズなルックローテーションを実現するためのカスタムソリューションが用意されています。
以下のログは、一般的なハードウェア(125Hzのマウスポーリング)と高いレンダリング/出力リフレッシュレート(200FPS以上)を使用した場合のRaw入力でのエイリアシングの問題を示しています。レンダリング出力は、CPU/GPUがどれほど優れていても、常にジッターを感じることになります。
この問題を解決するために、入力値をタイムスタンプで記録し、現在のフレームの値を定義された時間スパンの平均値として計算します(Fusion BRはデフォルトで25msのウィンドウを使用します)。この結果、滑らかな知覚が得られますが(特に高リフレッシュレートのモニターで顕著)、ごくわずかな入力遅延が発生します。より高いサンプリングレートのハードウェアを使用することで、スムージングウィンドウを最小にすることができます。
次のグラフは、生の マウスデルタ(下線)とキャラクターのルックローテーション(上線)を時間軸で示したものです。
次のグラフは、マウスのデルタ(下線)とキャラクターの視線回転(上線)を時間軸で平滑化したものです。
また、サンプリングエラー(机上面)や手やマウスの動きの不均一性(机上摩擦、筋肉)による微小ジッターを低減することができます。
キャラクターアニメーション
このプロジェクトでは、Playables APIをベースにしたカスタムアニメーションコントローラーの実装があります。これは、ティックアキュレートなアニメーション評価と動的なパフォーマンスのスケーリングに対応しています。
以下の図は、Mecanim
に類似したアーキテクチャを表しています。
エージェントのオブジェクト階層におけるアニメーションのレイヤーとステートの設定。
アニメーションのレイヤー:
Locomotion
:移動のためのベースフルボディレイヤーFullBody
: Locomotion とブレンドされたフルボディのオーバーライドレイヤーLowerBody
: 下半身のキャラクター回転用のオーバーライドレイヤー
-UpperBody
: 上半身のアクションのオーバーライドレイヤーです。Shoot
: 手の動作(射撃)のレイヤーをオーバーライドします。Look
: 上半身のレイヤーを追加して、上や下を向くようにします。
アニメーションコントローラの複雑さにもよりますが、200人のプレイヤーを評価することは、サーバーのボトルネックになりがちです。パフォーマンスを向上させるために、サーバーは接続されたプレーヤーの数に基づいて n 番目のフレームごとにインターレースされた PlayableGraph
を評価できるようにしています。レイヤーやステートの重みのような重要なプロパティは、依然として毎フレーム計算されます。次の表は、インターレース評価に関するルールを示しています。
接続されたプレイヤー | プレイアブルグラフの評価 |
---|---|
> 150 | 4フレーム毎 |
> 100 | 3フレーム毎 |
> 50 | 2フレーム毎 |
その他 | 毎フレーム |
キャラクターコントローラー
このサンプルでは、移動に Fusion KCC (高度なキネマティックキャラクターコントローラーアドオン) を使用しています。これは、パフォーマンス、ゲームプレイのインタラクション、カスタマイズに重点を置いた、一般的な低レベルキャラクターコントローラーです。
Fusion KCC の特徴:
- 位置と視線方向の回転(ピッチ+ヨー)の制御
- カプセルコライダーで定義された形状
- ローカルプレイヤーのレンダリング動作の予測
- ダイナミック(物理的)およびキネマティック(非現実的)な速度ベースの動きの組み合わせ
- 外力 - 爆発、移動するプラットフォームなどによるもの
- 加速度や摩擦の移動
- カスタマイズのための高度なKCCプロセッサーのパイプライン(速度と方向のオーバーライド、ブロッキング)
- デフォルトプロパティ(半径、高さ、質量など)のネットワーク同期、その他のプロパティの同期もオプションで可能
- カスタムコライダーフィルタリングと無視リスト
- CCD (連続衝突検出)
- コリジョンコールバック
- グランドスナップとステップ高さのサポート
- ローカルモード(ネットワークトラフィックなし)のサポート
- ネットワークとパフォーマンスの最適化
- プラットフォーム非依存、モバイルフレンドリー
- フレーム毎のデバッグの基本サポート - エディタ描画とロギング
プレイヤーの体力が一定以下になり、現在戦闘中でない場合、自動回復が作動し、プレイヤーの体力を補充し始めます。
ジェットパック
ジェットパックは、燃料を消耗しながら飛行し、レベル内を素早く移動する能力を提供します。燃料はアイテムボックスの中にある燃料缶を拾うことで補充することができます。
ジェットパックの状態は、燃料消費、プロペラ、サウンド、オン/オフの状態を処理する Jetpack
スクリプトによって処理されます。実際の空中の動きはJetpackKCCProcessor
によって処理さ れます。このスクリプトはKCC速度をオーバーライドし、デフォルトの挙動を抑制します。
観戦者モード
プレイヤーが脱落したり、ゲームに参加するのが遅れたりすると、観戦モードになります。観戦モードでは、プレイヤーは他のプレイヤーの視点からゲームを観察することができます。コード上では、これは実際には非常に単純に処理されます。カメラと UI は SceneContext
に割り当てられた ObservedAgent
に基づいて動作します。ObservedAgent
には、ローカルプレイヤーエージェントと観戦プレイヤーエージェントのどちらかを指定します。