💡
Meta Questでパススルー時に境界(Guardian)をオフにする方法【Unity】
前提
- Unity 6000以降
- MetaXRSDK v78を使用
- Meta XR Core SDKをインストール済み
- OpenXR を有効化済み
- PackageManagerからUnity OpenXR Metaをインストール済み
- シーンに OVRPassthroughLayer を1つ配置(パススルー描画用)
- MetaQuestビルドターゲットで Quest 実機 へデプロイ(Link/Editorでは抑制できません)
手順
AndroidManifest.xml に Boundaryless を宣言する
Asset/Pligins/Android/AndroidManifest.xml
に以下を追加。
<!-- 常時境界をオフにする場合 -->
<uses-feature
android:name="com.oculus.feature.BOUNDARYLESS_APP"
android:required="true" />
<!-- 状況に応じて境界をオフにする場合 -->
<uses-feature
android:name="com.oculus.feature.CONTEXTUAL_BOUNDARYLESS_APP"
android:required="true" />
<!-- パススルーを使うなら推奨 -->
<uses-feature
android:name="com.oculus.feature.PASSTHROUGH"
android:required="true" />
これを入れておくことで、アプリが「境界抑制可能」と認識されます。
XR Plug-in Managementの設定を有効化する
赤枠三点を有効化にする。
シーンに境界無効化を呼び出すコンポーネントを配置する
以下のクラスを作成し、シーン内に配置する。
using System.Collections;
using UnityEngine;
/// <summary>
/// 起動時に Passthrough を有効化し、Guardian/Boundary の可視化を抑制します。
/// OVR Plugin 使用前提(OVRManager / OVRPassthroughLayer)
/// </summary>
[DefaultExecutionOrder(-1000)]
public class OVRBoundarySuppressor : MonoBehaviour
{
[Header("Behavior")]
[Tooltip("シーン開始時に自動で抑制します")]
public bool suppressOnStart = true;
[Tooltip("抑制リクエストを出す前に数フレーム待機(初期化待ち)")]
public int warmupFrames = 1;
[Header("Optional References")]
[Tooltip("シーン内の OVRPassthroughLayer。未指定なら自動検索します")]
public OVRPassthroughLayer passthroughLayer;
private bool _isSuppressed;
private void Reset()
{
// 自動で見つけておく
passthroughLayer = Object.FindFirstObjectByType<OVRPassthroughLayer>();
}
private void Awake()
{
if (passthroughLayer == null)
passthroughLayer = Object.FindFirstObjectByType<OVRPassthroughLayer>();
}
private void Start()
{
if (suppressOnStart)
StartCoroutine(CoSuppressAfterWarmup());
}
private IEnumerator CoSuppressAfterWarmup()
{
// OVR 初期化待ち(必要に応じてフレーム数を調整)
for (int i = 0; i < Mathf.Max(0, warmupFrames); i++)
yield return null;
EnsurePassthroughEnabled(true);
SetBoundarySuppression(true);
}
/// <summary>
/// Passthrough の有効/無効を切り替え
/// </summary>
public void EnsurePassthroughEnabled(bool enabled)
{
if (passthroughLayer == null)
passthroughLayer = Object.FindFirstObjectByType<OVRPassthroughLayer>();
if (passthroughLayer != null)
passthroughLayer.enabled = enabled;
else
Debug.LogWarning("[OVRBoundarySuppressor] OVRPassthroughLayer が見つかりません。シーンに追加してください。");
}
/// <summary>
/// 境界可視化の抑制/解除
/// </summary>
public void SetBoundarySuppression(bool enable)
{
#if !UNITY_ANDROID
Debug.LogWarning("[OVRBoundarySuppressor] 現在のプラットフォームでは Boundary 抑制が動作しない場合があります(Quest 実機でご確認ください)。");
#endif
// OVRManager.instance が null のケースがあるため、ステートックプロパティ経由に統一
if (OVRManager.instance != null)
{
OVRManager.instance.shouldBoundaryVisibilityBeSuppressed = enable;
}
else
{
Debug.LogWarning("[OVRBoundarySuppressor] OVRManager.instance が見つかりません。シーンに OVRManager を追加してください。");
}
_isSuppressed = enable;
Debug.Log($"[OVRBoundarySuppressor] Boundary suppression request: {enable}");
}
/// <summary>
/// トグル用(UIボタンやデバッグキーから呼べます)
/// </summary>
public void ToggleSuppression()
{
SetBoundarySuppression(!_isSuppressed);
}
}
まとめ
- Manifest に BOUNDARYLESS_APP / CONTEXTUAL_BOUNDARYLESS_APP / PASSTHROUGH を宣言
- OpenXR の Boundary Visibility / Camera (Passthrough) / Session を有効化
- OVRBoundarySuppressor をシーンに置いて起動時に抑制をリクエスト
これで パススルー時に境界(Guardian)を非表示 にできます。
Discussion