VRCCameraSettings
ユーザーのスクリーンカメラ、ハンドヘルドカメラ、およびUnityのグローバル品質設定に関する情報と限定的な制御機能を、ここに記載されたAPIを通じて提供します。
このクラスの2つのインスタンスには、以下の静的アクセサーを通じてアクセスできます。
VRCCameraSettings.ScreenCamera: ユーザーのスクリーンカメラ。つまり、現在表示されている描画内容です(VRモード中のユーザーであればステレオカメラとなります)。VRCCameraSettings.PhotoCamera: ユーザーのハンドヘルドフォトカメラ。注意点として、このインスタンスのプロパティはユーザーがカメラを有効にしている場合にのみ更新されます。その確認にはActiveプロパティを使用してください。また、このプロパティは常にプレビュー画像を描画しているカメラを指すものであり、写真撮影そのものやストリームカメラのビューを描画するカメラを指すわけではないことにも注意してください(ただし、シャッターが押されるたびに、ほとんどのプロパティはそのカメラと同期されます)。- ⚠️ ClientSimでは、フォトカメラが利用できないため、このプロパティは
nullとなります。実際のVRChatクライアントでは、nullになることはありません。
これら2つのプロパティが、内部的に必ずしも単一の実際の Camera コンポーネントを参照しているとは限りません。VRChatが複雑な部分を抽象化しているため、開発者がこれを気にする必要は基本的にありません。しかし、完全性のために以下の点に留意してください。
VRCCameraSettings.ScreenCameraのプロパティを変更すると、Focus View カメラが影響を受けます。- 同様に、ハンドヘルドカメラが「Stream Camera」モードで開かれている間は、
VRCCameraSettings.PhotoCameraにアクセスすると、その際に使用されているコンポーネントが影響を受けます。 VRCCameraSettings.PhotoCameraは、Dolly Multi Camセットアップで使用されるすべてのカメラにもリンクされていますが、FieldOfViewなどの一部のプロパティはそれらの間で異なる場合があります。その場合、最初のカメラの設定が返されます。
高度なユースケースでは、この状態を CameraMode プロパティを通じて読み取ることができます。
公開されているプロパティ
これらのインスタンスは、Unityの Camera クラスの特定のプロパティを公開します(これらのプロパティの詳細についてはUnityのドキュメントを参照してください)。安全上の理由から、生の Camera コンポーネントにアクセスすることはできませんので注意してください。ただし、ワールドに手動で配置したコンポーネントについては、 Camera クラスが公開されています。
現在 読み取り専用 として公開されているもの:
Vector3 Position: ワールド空間での位置Quaternion Rotation: ワールド空間での回転Vector3 Forward: ワールド空間での前方ベクトル(利便性のため)Vector3 Up: ワールド空間での上方ベクトル(利便性のため)Vector3 Right: ワールド空間での右方ベクトル(利便性のため)int PixelWidthおよびint PixelHeight: 現在のレンダリングターゲットのサイズ(ピクセル単位。VRのスーパーサンプリング設定の影響を受ける場合があります)float Aspect: 現在のレンダリングターゲットのアスペクト比float FieldOfView: カメラの現在の「垂直」視野角(VRユーザーの場合は正確でない可能性があります)bool Active: カメラが現在描画中かどうか。ScreenCameraでは常に true となり、PhotoCameraを介してハンドヘルドカメラを検出するのに役立ちます。また、Spoutストリーミングが有効な間は、PhotoCameraに対してtrueが有効になります。bool StereoEnabled: ユーザーがVRモードの場合、ScreenCameraに対してtrueを返します。VRユーザーの検出には、Player API を使用することを推奨します。
Active が false である場合、 Position や Rotation などのトランスフォームデータはすべて0になります。その場合、 Forward/Up/Right はそれぞれ Vector3.forward/up/right を返します。
現在 読み取り・書き込み可能 として公開されているもの:
float NearClipPlaneおよびfloat FarClipPlane: ランタイム時にカメラのクリッピング面を調整できます。これにはシーンディスクリプタの Reference Camera を介して設定する場合と同様の制限が適用されます。NearClipPlaneは、ユーザーの「Forced Camera Near Distance」設定によって調整される場合があります。値を設定した後に再度読み取ることで、この調整が行われたかどうかを検出できます。NearClipPlaneは、0.001と0.05の間にクランプ(制限)されます。FarClipPlaneは、最低でもNearClipPlaneよりも0.1高い値にしか設定できず、これらはクランプされます。- ユーザーの「Forced Camera Near Distance」設定が「Dynamic」になっている場合、
FarClipPlaneを調整するとNearClipPlaneも調整されることがあります。 bool AllowHDR: カメラがレンダリングターゲットに対して HDR 値を送信するかどうか。DepthTextureMode DepthTextureMode: カメラの深度テクスチャレンダリングを有効にするために使用できます。これは特定のシェーダーエフェクトに役立ちます。これを、影付きのリアルタイムライトの代わりに使用して、カメラの深度テクスチャを強制的に生成させることができます。ただし、シーン内にそのようなライトが存在してもDepthTextureModeプロパティは変化しないことに注意してください。つまり、このプロパティからNoneという値を読み取ったからといって、深度パスを強制的にレンダリングさせる深度ライトがシーン内に存在しないとは限りません。PhotoCameraには常にDepthTextureMode.Depthが有効化されており、これを無効にすることはできませんが、他のオプションを追加することは可能です。bool UseOcclusionCulling: レンダリング中にカメラがオクルージョンカリングを使用するかどうか。デフォルトはtrueですが、ワールドにベイクされたオクルージョンデータがある場合にのみ効果を発揮します。bool AllowMSAA:falseに設定すると、ユーザー設定に関係なく、このカメラ上のすべての MSAA(アンチエイリアシング)を無効にします。デフォルトはtrueであり、その場合はユーザーのグラフィック設定が使用されます。LayerMask CullingMask: メインカメラによってレンダリングされるレイヤーを設定します。このプロパティのセッターは、ScreenCamera以外が指定されると例外をスローします。いかなるreservedレイヤー、MirrorReflection、およびInternalUIも変更できません。カメラスタッキングのため、一部のプラットフォームで可視状態であってもInternalUIが 0 を返す可能性があることに注意してください。CameraClearFlags ClearFlags: このカメラをレンダリングする際に使用する背景のクリアモードを設定します。Color BackgroundColor:ClearFlagsがSolidColorに設定されている場合に使用される色。bool LayerCullSpherical: ~~Unity Docs を参照してください。~~ この API は現在 Udon では無効になっています(UI カリングの問題を引き起こすため)。設定しても何も起こりません(no-op)。float[] LayerCullDistances: Unity Docs を参照してください。配列は GameObject レイヤーに対応する 32 個のエントリを持つ必要があります。あるレイヤーに対して0という値は、FarClipPlaneの値が使用されることを意味します。このプロパティをnullに設定することは、すべてのレイヤーに対して0を渡すことと同じです。FarClipPlaneと同様に、これは最小値NearClipPlane + 0.1にクランプされます。いかなるreservedレイヤーおよびInternalUIも変更できず、常に0として読み取られます。
Camera Mode
CameraMode プロパティは ScreenCamera および PhotoCamera で利用可能です。
ScreenCamera には以下のカメラモードがあります。
| モード | 説明 |
|---|---|
| Screen | ユーザーの現在の視点をレンダリングするためのデフォルトモード。 |
| FocusView | モバイルデバイスで Focus View を使用しているときにアクティブになります。 |
PhotoCamera には以下のカメラモードがあります。
| Mode | Description |
|---|---|
| PhotoOrVideo | カメラが写真またはストリームモードです。絵文字やステッカーなどのモードを含みます。 |
| カメラの「Prints」スキンが有効になっています。 | |
| DroneHandheld | カメラがドローンモードです。 |
| DroneFPV | ユーザーがドローンをFPVモードで操縦しています。 |
| Unknown | Active が false である場合に設定されます。 |
静的関数
主にVRユーザー向けに、VRCCameraSettings で2つの静的関数が公開されています。
Vector3 GetEyePosition(Camera.StereoscopicEye eye): 指定された目のワールド空間位置を返します。VR以外のユーザーにおけるScreenCamera.Positionと同等です。Quaternion GetEyeRotation(Camera.StereoscopicEye eye): 指定された目のワールド空間回転を返します。VR以外のユーザーにおけるScreenCamera.Rotationと同等です。
さらに、汎用的な関数が1つ存在します。
void GetCurrentCamera(out VRCCameraSettings internalComponent, out Camera externalComponent): これは Camera.current の代替であり、レンダリングイベント中にのみ値が設定されます。- 既知の内部カメラがレンダリングしている場合、
internalComponentにはVRCCameraSettings.ScreenCameraまたはVRCCameraSettings.PhotoCameraが含まれ、externalComponentはnullとなります。 - ワールド内のカスタムカメラがレンダリングしている場合、
internalComponentはnullとなり、externalComponentにはUnityEngine.Cameraコンポーネントが含まれます。 Camera.currentがnullである場合、または Udonがアクセスできないカメラ(例:アバター上のUnityEngine.Camera)がレンダリングされている場合、どちらの結果もnullになります。 ⚠️ アバターカメラが存在しない場合であっても、レンダリングイベント中を含め、この関数がいつでも両方の結果に対してnullを返す可能性があります。これは、VRChatが組み込みメニューなどのために内部レンダリングステップを使用しているためです。Udonスクリプトでこのケースを必ず処理するようにしてください。
- 既知の内部カメラがレンダリングしている場合、
OnChanged イベント
ユーザーが「Near Clip Override」などの特定のグラフィック設定を変更すると、OnVRCCameraSettingsChanged イベントがトリガーされます。
このイベントは毎フレーム、あるいは1フレーム中に複数回トリガーされる可能性があります。パフォーマンスへの影響を避けるため、処理は最小限に抑えることを推奨します。
例

using TMPro;
using UdonSharp;
using UnityEngine;
using UnityEngine.UI;
using VRC.SDK3.Rendering;
public class CameraInfoDisplay : UdonSharpBehaviour
{
[SerializeField] private TextMeshProUGUI info;
void Start()
{
// call it once to initialize
OnVRCCameraSettingsChanged(VRCCameraSettings.ScreenCamera);
Debug.Log($"Started CameraInfoDisplay at resolution of {VRCCameraSettings.ScreenCamera.PixelWidth}x{VRCCameraSettings.ScreenCamera.PixelHeight}");
Debug.Log($"The handheld photo camera is {(VRCCameraSettings.PhotoCamera.Active ? "enabled" : "disabled")}");
}
// will be called if resolution or a couple other properties change
public override void OnVRCCameraSettingsChanged(VRCCameraSettings camera)
{
// ignore handheld photo camera
if (camera != VRCCameraSettings.ScreenCamera)
return;
info.text = $"{camera.PixelWidth}x{camera.PixelHeight} fov={camera.FieldOfView} frame={Time.frameCount}°";
}
}
最終更新: