概要
自分のアバターの姿を確認できる鏡(ミラー) は、VRChatのソーシャル体験において非常に重要なオブジェクトです。多くのユーザーは、ワールドに入るとまず鏡を探します。しかし、ミラーはワールドのパフォーマンスに最も大きな影響を与える要素の一つでもあります。
そのため、ミラーは単に設置するだけでなく、必要な時にだけ有効化し、パフォーマンスと品質のバランスを調整できるように実装することが、快適なワールドを作る上で不可欠です。
本記事では、VRCMirrorReflectionコンポーネントをUdonSharpで制御し、オン/オフ機能や品質設定機能を備えた、実用的なミラーシステムの構築方法を解説します。
ステップ1: VRCMirrorReflectionコンポーネントの設定
- オブジェクトの作成: シーンに鏡の反射面となる
Quadを作成します。Quadはデフォルトで前方向(Z+)を向いているため、回転なしでそのまま垂直ミラーとして使用できます。注意:Planeを使用してX軸を-90度回転させると、ミラーの映像が上下反転することがあります。 VRCMirrorReflectionの追加: 作成したオブジェクトにVRCMirrorReflectionコンポーネントを追加します。これだけで、オブジェクトは鏡として機能し始めます。- 初期状態の設定: パフォーマンスのため、鏡のGameObjectはデフォルトで非アクティブにしておくのが一般的です。つまり、Inspectorの左上にあるチェックボックスを外しておきます。
VRCMirrorReflectionの主要な設定項目

m_ReflectLayers: 鏡にどのレイヤーのオブジェクトを映すかを選択します。デフォルトでは全てを映しますが、例えばPlayerレイヤーのみに限定することで、プレイヤーアバターだけを映す鏡(ダンス練習用など)を作ることができ、負荷を大幅に軽減できます。注意:Waterレイヤーはミラーに描画されません。m_DisablePixelLights:trueにすると、ミラー内の描画でピクセルライト(Point Lightなど)が無効になり、負荷が軽減されます。- Mirror Resolution(解像度): ミラーの解像度設定です。
AutoはユーザーのHMDまたはモニター解像度に合わせますが、最大2048×2048に制限されます。VRの場合は片目あたりの解像度となります。値を下げると負荷は軽くなりますが画質は粗くなります。Unlimitedは制限なしですが、非常に高負荷になるため注意が必要です。
実装例1: シンプルなオン/オフボタン
ボタンをクリックすると、ミラーのGameObjectがアクティブ/非アクティブに切り替わる、最も基本的なローカル制御のミラーです。ミラーの状態は各プレイヤーの環境でのみ変化し、他のプレイヤーには影響しません。

Unityでの設定
- ミラーオブジェクトを作成し、デフォルトで非アクティブにしておきます。
- ミラーを制御するためのボタン(例: Cube)をシーンに配置し、
ColliderとUdon Behaviourを追加します。Interaction Textに「ミラーON/OFF」などと設定します。
スクリプト: LocalMirrorSwitch.cs
using UdonSharp;
using UnityEngine;
public class LocalMirrorSwitch : UdonSharpBehaviour
{
[Tooltip("制御するミラーのGameObjectを割り当てます。")]
public GameObject mirrorObject;
public override void Interact()
{
if (mirrorObject != null)
{
// ミラーのGameObjectのアクティブ状態を反転させる
mirrorObject.SetActive(!mirrorObject.activeSelf);
}
}
}
Unityでの最終設定
LocalMirrorSwitch.csをボタンのUdon Behaviourに割り当てます。- スクリプトの
Mirror Objectフィールドに、非アクティブにしてあるミラーのGameObjectをドラッグ&ドロップします。
これで、各プレイヤーは自分の好きなタイミングで、自分にだけ見えるミラーをオン/オフできるようになります。これはワールドに必須とされる基本的な機能です。
実装例2: 品質設定機能付きミラーシステム
オン/オフだけでなく、「高」「 中」「低」といった品質を選択できる、より高度なミラーシステムです。品質に応じて、ミラーに映すレイヤーを動的に変更します。

この実装では、マネージャースクリプトとボタン用スクリプトの2つを使用します。
スクリプト1: MirrorSystemManager.cs(マネージャー)
ミラーの状態と品質設定を管理する中心的なスクリプトです。
using UdonSharp;
using UnityEngine;
using VRC.SDK3.Components;
public class MirrorSystemManager : UdonSharpBehaviour
{
[Tooltip("制御するミラーのVRCMirrorReflectionコンポーネント")]
public VRCMirrorReflection mirror;
// レイヤーマスクの定義
private int highQualityLayers = -1; // 全て
private int mediumQualityLayers = (1 << 9) | (1 << 10); // PlayerとPlayerLocalのみ
private int lowQualityLayers = (1 << 10); // PlayerLocal (自分) のみ
public void ToggleMirror()
{
if (mirror != null)
{
mirror.gameObject.SetActive(!mirror.gameObject.activeSelf);
}
}
public void SetQualityHigh()
{
if (mirror != null)
{
mirror.m_ReflectLayers = highQualityLayers;
}
}
public void SetQualityMedium()
{
if (mirror != null)
{
mirror.m_ReflectLayers = mediumQualityLayers;
}
}
public void SetQualityLow()
{
if (mirror != null)
{
mirror.m_ReflectLayers = lowQualityLayers;
}
}
}
スクリプト2: MirrorButton.cs(各ボタン用)
各ボタンにアタッチし、クリック時にマネージャーのメソッドを呼び出します。
using UdonSharp;
using UnityEngine;
public class MirrorButton : UdonSharpBehaviour
{
[Tooltip("MirrorSystemManagerへの参照")]
public MirrorSystemManager mirrorSystem;
[Tooltip("ボタンの動作: 0=ON/OFF, 1=高品質, 2=中品質, 3=低品質")]
public int actionType;
public override void Interact()
{
if (mirrorSystem == null) return;
switch (actionType)
{
case 0:
mirrorSystem.ToggleMirror();
break;
case 1:
mirrorSystem.SetQualityHigh();
break;
case 2:
mirrorSystem.SetQualityMedium();
break;
case 3:
mirrorSystem.SetQualityLow();
break;
}
}
}
Unityでの設定手順
-
マネージャーの設定:
- 空のGameObject(例:
MirrorSystemManager)を作成し、MirrorSystemManager.csをアタッチ MirrorフィールドにミラーのVRCMirrorReflectionコンポーネントを割り当て
- 空のGameObject(例:
-
ボタンの設定(4つのボタンそれぞれに):
- Cubeなどでボタンを作成し、
ColliderとMirrorButton.csをアタッチ Mirror Systemフィールドに上記のマネージャーオブジェクトを割り当てAction Typeを設定:- ON/OFFボタン →
0 - 高品質ボタン →
1 - 中品質ボタン →
2 - 低品質ボタン →
3
- ON/OFFボタン →
- Cubeなどでボタンを作成し、
m_ReflectLayersはLayerMask型ですが、Udonでは直接扱えないため、int型としてビット演算でレイヤーマスクを構築しています。1 << レイヤー番号で特定のレイヤーのみを含むマスクを作成し、|(ビット単位OR)でそれらを組み合わせます。
まとめ
- ミラーは非常に高負荷なため、デフォルトでオフにし、プレイヤーが任意にオン/オフできる機能を実装することが強く推奨されます。
- 最も簡単な実装は、ボタンの
InteractでミラーのGameObjectのSetActive()を切り替えることです。これはローカル処理で十分です。 VRCMirrorReflectionのm_ReflectLayersプロパティをUdonから変更することで、ミラーに映すオブジェクトを動的に制御できます。これにより、パフォーマンスと用途に応じた品質設定が可能になります。- レイヤーマスクをUdonで扱うには、
int型とビット演算の知識が必要になります。
快適なVRChat体験を提供するためには、パフォーマンスへの配慮が欠かせません。特にミラーは、その影響が最も大きい要素の一つです。ユーザーフレンドリーなミラーシステムを実装することは、ワールド制作者の重要な責務と言えるでしょう。