プレイヤー
ClientSimにおけるプレイヤーの表現は、CyanEmuと比較して多くのコンポーネントに分割されています。各コンポーネントがプレイヤーの異なる側面を処理します。以下に、ローカルプレイヤーとリモートプレイヤーの両方のプレハブの階層構造を示します。

ClientSimPlayer
ClientSimPlayerクラスは、プレイヤーに関するすべてのシステムを保持するコンテナです。ローカルプレイヤーとリモートプレイヤーの両方にClientSimPlayerが存在しますが、初期化されるのはローカルプレイヤーのみです。AvatarとVRCPlayerApiの変更可能なデータを除き、リモートプレイヤーのすべてのシステムは空のままとなります。ClientSimPlayerは、Playerプレハブの最上位オブジェクトにある最初のコンポーネントです。インスペクターでは、実行時にLocomotion SettingsやAudio SettingsといったVRCPlayerApiのデータを表示および変更できます。
TrackingProvider
TrackingProviderインターフェースは、プレイヤーのトラッキングデータをどのように制御するかを定義するための汎用的な手段です。抽象クラスであるTrackingProviderBaseは、頭、手、およびプレイスペースの位置に関するデータを提供し、頭の高さに基づいてプレイヤーの現在の姿勢を決定します。トラッキングプロバイダーはスケーリングが可能で、プレイヤーカメラを上下に移動させることで、さまざまなプレイヤーアバターのシナリオをテストするのに役立ちます。このクラスはPlayerHeightUpdateイベントをリッスンし、要求されたプレイヤーの高さに基づいて新しいトラッキングスケールを計算します。デフォルトのアバターの高さは1.9で、これはTrackingScale 1に相当します。このクラスは抽象クラスであるため、ClientSimで使用するには継承する必要があります。現在、ClientSimにはDesktopTrackingProviderのみが含まれています。ClientSimでVRを実装する場合は、新しいVRTrackingProviderが必要になります。トラッキングプロバイダーはPlayerControllerの子であることが想定されていますが、VRを実装する際はプレイスペースのx/zオフセットがPlayerControllerに適用されないため、再検討が必要です。
DesktopTrackingProvider
現在、ClientSim用に実装されている唯一のTrackingProviderです。このトラッキングプロバイダーは、手の位置をカメラに対して固定します。カメラの高さはCrouch and Prone Input Eventsに基づいて変更されます。このトラッキングプロバイダーは毎フレーム、視点(look)入力の変更を確認し、カメラのX回転(上下)を更新します。プレイヤーがステーションに座っている場合、頭部のY回転のロックが解除され、プレイスペースの回転から最大90度まで左右を見渡せるようになります。
PlayerController
PlayerControllerは現在、プレイヤーの移動のみを制御します。CyanEmuでは、PlayerControllerクラスがプレイヤーに関連するすべてを保持していましたが、現在はこれらのシステムが分離され、PlayerControllerはプレイヤーの移動処理に専念するようになっています。コントローラーは毎フレーム、移動入力およびTrackingProviderの姿勢を確認し、そのフレームでプレイヤーがどれだけ移動すべきかを判断します。
PlayerStationManager
PlayerStationManagerは、プレイヤーがステーションとどのように相互作用するかを管理します。プレイヤーが現在どのステーションにいるか、またプレイヤーがそのステーションに固定されているかどうかを保持します。ステーションに固定されている間、フレームの最後において、すべてのUpdate、LateUpdate、およびFixedUpdateメソッドに対して、PlayerControllerの位置がステーションの位置へと更新されます。これは、ステーションの位置を変更する他のすべてのスクリプトが先に実行されることを保証するため、フレームの最後に行われます。
InteractManager
InteractManagerは、特定のGameObjectが操作可能かどうかを判断し、その操作を実行する役割を担います。これは、TrackingProviderの現在のTrackingScaleと各Interactの近接値を使用して、プレイヤーが操作可能な現在の距離を計算します。
Raycaster
ClientSimのインタラクト検出はRaycasterを通じて処理されます。このシステムは、Physics.Raycastで使用される指定のレイに基づいてInteractableを検索します。レイキャスト時にどのレイヤーを考慮するかは、InteractiveLayerProviderを使用して判断されます。ヒットしたすべてのオブジェクトは、検出されたコンポーネントに基づいてフィルタリングされます。UIShapeを持つオブジェクトが常に最優先されます。InteractManagerは、オブジェクト上でインタラクト可能なコンポーネントを特定するために使用されます。レイキャストごとにRaycastResultが返されます。これには、レイに関する情報、ヒットしたオブジェクト、および(存在する場合は)インタラクト可能なタイプが含まれます。
RayProvider
RaycasterはRayProviderを使用して、レイキャストを行う方向と起点を判断します。RayProviderは、詳細な仕様を意識せずにレイを提供するための汎用的な手段です。ClientSimには2つのRayProviderが実装されています:
CameraRayProvider
カメラと現在のマウス位置から、カメラからマウスを通るレイを作成します。これはTrackingProviderがVR以外に設定されている場合に使用されるRayProviderです。
TransformRayProvider
Transformを指定し、その位置と前方方向に基づいてRayを作成します。これは、TrackingProviderがVRに設定されている場合に手元からレイキャストを行うために使用されます。
PlayerRaycaster
PlayerRaycasterは、ワールド内のインタラクト対象を検索し、その結果に基づいてイベントを送信する役割を担います。また、左右両方のPlayerHandシステムを更新します。初期化時に、PlayerRaycasterは左右の手のためにそれぞれ1つずつ、合計2つのRaycastersを作成します。TrackingProviderがVRではない(デスクトップモードである)場合、右手はマウスベースのRayProviderを持つRaycasterを使用します。左手はVR環境以外では使用されないため、初期化されません。TrackingProviderがVR環境にある場合、左右のRaycasterはTrackingProviderのハンドトランスフォームを使用した、トランスフォームベースのRayProviderで初期化されます。毎フレーム、両手のRaycasterシステムが更新されてInteractablesが検索され、その結果がEventDispatcherを通じて送信されます。最後に発見されたインタラクト対象は、それぞれの手の「ホバー中インタラクト対象」として保存されます。ホバー中のインタラクト対象がPickupableである場合、そのPickupableは該当するPlayerHandの「ホバー中Pickupable」として設定されます。インタラクト対象にホバーしている状態で、該当する手のUse Inputアクションが発生すると、そのホバーしているオブジェクトに対してインタラクトが実行されます。
PlayerHand
PlayerHandシステムは、Pickupableオブジェクトを管理する役割を担います。PlayerRaycasterが現在ホバーされているピックアップを設定し、PlayerHandがホバーされているPickupableをいつ拾うかというGrab Input Eventsを監視します。また、PlayerHandはUseやDropイベントを監視して、現在保持しているピックアップに対してアクションを実行します。ピックアップがkinematicの場合、その位置はPlayerHandのrigidbodyのトランスフォームに一致するように毎フレーム直接設定されます。ピックアップがnon kinematicの場合は、Fixed Jointを使用してPlayerHandのrigidbodyにアタッチされます。右手にピックアップを持っている間は、様々なManipulateバインディングを使用してピックアップを操作できます。
PlayerAvatarManager
PlayerAvatarManagerは、プレイヤーのアバターに関連する項目を管理します。ローカルプレイヤーとリモートプレイヤーの双方にAvatar Managerが存在します。すべてのプレイヤーのアバターは、デフォルトではVRChatのロボットになっています。このマネージャーは、VRCPlayerApiに対してアバター情報を提供する役割を担っています。GetBonePositionおよびGetBoneRotationは、Animator.GetBoneTransformのラッパーとしてここで実装されています。ローカルプレイヤーのアバターマネージャーのみが適切に初期化されており、それによってTrackingScaleの変更Eventsをリッスンし、新しいトラッキングスケールに合わせてアバターのスケールを更新できるようになっています。
レティクル
ClientSimReticleシステムは、UnityのGameウィンドウの中央にレティクルアイコンを表示する役割を担います。このシステムはDesktopTrackingProviderでのみ有効にする必要があります。レティクルは設定メニューから無効にできます。中央のレティクルに加え、PlayerRaycasterがUIShapeを持つオブジェクトに重なると、マウス位置にポインターが表示されます。このポインターは画面中央に限定されることはなく、マウスボタンを離しても表示され続けます。マウスの位置はClientSimBaseInputから提供されます。
最終更新: