Chapter 5 - Final
目標
2つのデバイスタイプ間で共同作業の体験をつくります
ビルドするもの
第4章に基づいています。島内のパズルにImmersiveデバイスユーザーが近づくと,HoloLensユーザーはパズルを解くヒントツールを取得します。Immersiveデバイスユーザーが皆パズルを通過し,ロケットルーム内の"ready pad"にたどり着くと,ロケットが発射されます。
Steps
・HierarchyでUslandを選択する
・Inspectorで,Level Control内のEnable Collaborationにチェックを入れる
コードを理解する
LevelControl.csを見てみましょう。このスクリプトはゲームロジックのコアであり,ゲーム状態を保持しています。UNETを利用したマルチプレイヤーゲームなので,少なくともチュートリアルを修正できるようにデータがどのように流れているか理解する必要があります。
Assets\AppPrefabs\Support\Scripts\GameLogicからLevelControl.csをダブルクリックして開いてください。
Immersiveデバイスがどのようにロケットを発射する準備をするか理解しましょう。ロケットの発射準備は,島の3つの道に対応するそれぞれのboolのうちの一つを設定すると伝達されます。ユーザーが道に配置された時に設定される道のbool値はロケットルーム内の茶色いパッド上にあります。それでは,詳細に移りましょう。
Update関数から始めます。'チート'機能があることに気が付くでしょう。これは開発中に,ロケット発射をテストし,またシーケンスをリセットするために使われます。
これはマルチユーザー体験では機能しません。上手くいけば,次の情報を内部化する時までに、それを機能させることができます。チートすべきかどうかを確認した後,ローカルプレイヤーが没入しているかを確認します。ゴールにしたことを検出するをに焦点を当てます。(Immersed)チェックの内部では,EnableCollaboration の中でCheckGoalの呼び出しがあります。これは,この章のステップを完了している間にチェックされたチェックボックスに関与します。EnableCollaboration の内部では,CheckGoal()を呼んでいることが確認できます。
CheckGoal はパッド上に多かれ少なかれ立っているかどうかを確認するための計算をしています。Debug.Log "Arrived at goal"とSendAtGoalMessage()を呼び出します。SendAtGoalMessage ではplayerController.SendAtGoalを呼び出します。時間を省くためにここにコードを載せます。
PlayerController.cs 内
SendAtGoalMessageがLevelControl.csの背後でlevelState.SetGoalIndexを呼び出すCmdSendAtGoalを呼んでいることに注目してください。一見これは奇妙に見えるでしょう。なぜSetGoalIndexを呼ぶのではなくプレイヤーコントローラーを介したこの奇妙なルーティングなのでしょう?この理由は,同期するデータを保持するためUNETが使用するデータモデルに準拠しているからです。不正行為やスラッシングを防ぐため,UNETは各オブジェクトにどのユーザーが同期中の変数を変更可能な権利を有するかを確認します。更にホスト(セッションを開始したユーザー)のみがデータを直接変更することができます。ホストではないユーザーは権利は持つも,変数を変更できるホストにコマンドを送る必要があります。デフォルトではホストはユーザーを示すオブジェクトを除いた全てのオブジェクトに対して権限を持ちます。この場合,オブジェクトはplayercontroller スクリプトを持っています。オブジェクトに対する権限を要求し変更する方法もありますが,プレイヤーコントローラには自身の権限とプレイヤーコントローラを介したルートコマンドがあるという優位性を選択します。
言い換えれば,自分の目標に到達したら,プレイヤーはホストに通知する必要があり,ホストは他のユーザーに通知する必要があるということです。
LevelControl.csの背後では,SetGoalIndexを見ています。ここでは,synclist (AtGoal)の変数の値を設定します。この操作をする間,ホストであるということに気を留めておいてください。コマンドと同様に,PRCはホストが発行できるものであり,全てのクライアントにいくつかのコードを実行させます。
ここでは”RpcCheckAllGoals”と呼びましょう。各クライアントは個々に3つのAtGoals が設定されているかを確認し,そうであればロケットを発射します。