대화중에 아웃라인 안뜨게

This commit is contained in:
2026-07-17 11:57:19 +09:00
parent ecfd2d7f47
commit ad6ccadc8e
4 changed files with 91 additions and 2 deletions

View File

@@ -0,0 +1,56 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;
using UnityEngine.XR.Interaction.Toolkit.Interactors;
// 대화 중(선택 메뉴 포함) 월드 상호작용을 차단한다 — UI 상호작용은 유지.
// XR Origin(리그 루트)에 붙이면 자식의 모든 인터랙터를 찾아서, 대화가 시작될 때
// Interaction Layer를 None으로 바꿔 3D 인터랙터블과의 호버/선택/활성화를 막는다.
// 캔버스 UI(선택지 버튼 등)는 인터랙션 레이어를 거치지 않고 XRUIInputModule로
// 처리되므로 영향받지 않는다. 대화가 끝나면 원래 레이어로 복원.
public class DialogInteractionBlocker : MonoBehaviour
{
[Tooltip("차단에서 제외할 인터랙터 (예: 대화 중에도 텔레포트를 허용하고 싶을 때 텔레포트 레이 인터랙터)")]
[SerializeField] private List<XRBaseInteractor> _exclude = new();
// 차단 직전의 원래 레이어 — 복원용. 비어있지 않으면 차단 중이라는 뜻.
private readonly Dictionary<XRBaseInteractor, InteractionLayerMask> _saved = new();
private void OnEnable()
{
DialogPlayer.AnyActiveChanged += OnDialogActiveChanged;
if (DialogPlayer.IsAnyActive) Block(); // 이미 대화 중에 활성화된 경우
}
private void OnDisable()
{
DialogPlayer.AnyActiveChanged -= OnDialogActiveChanged;
Restore();
}
private void OnDialogActiveChanged(bool active)
{
if (active) Block();
else Restore();
}
private void Block()
{
if (_saved.Count > 0) return; // 이미 차단 중
// 매번 새로 수집 — 손에 든 도구 등 런타임에 생긴 인터랙터도 포함되게
foreach (var interactor in GetComponentsInChildren<XRBaseInteractor>(true))
{
if (_exclude.Contains(interactor)) continue;
_saved[interactor] = interactor.interactionLayers;
interactor.interactionLayers = 0; // None — 3D 인터랙터블 전부 차단
}
}
private void Restore()
{
foreach (var kvp in _saved)
if (kvp.Key != null) kvp.Key.interactionLayers = kvp.Value;
_saved.Clear();
}
}