히든제스처

This commit is contained in:
2026-07-23 13:08:43 +09:00
parent e1c43c9b3d
commit de5fe5b85a
109 changed files with 10034 additions and 135 deletions

View File

@@ -5,14 +5,24 @@
// 대화 중(선택 메뉴 포함) 월드 상호작용을 차단한다 — UI 상호작용은 유지.
// XR Origin(리그 루트)에 붙이면 자식의 모든 인터랙터를 찾아서, 대화가 시작될 때
// Interaction Layer를 None으로 바꿔 3D 인터랙터블과의 호버/선택/활성화를 막는다.
// Interaction Layer를 (기본) None으로 바꿔 3D 인터랙터블과의 호버/선택/활성화를 막는다.
// 캔버스 UI(선택지 버튼 등)는 인터랙션 레이어를 거치지 않고 XRUIInputModule로
// 처리되므로 영향받지 않는다. 대화가 끝나면 원래 레이어로 복원.
//
// _keepActiveDuringDialog에 레이어를 넣으면, 대화 중에도 그 레이어의 인터랙터블만 상호작용된다.
// 예: 대화 중에 꽃다발을 잡아서 NPC에게 건네야 하는 상황 — 꽃다발(XRGrabInteractable)을 그 레이어에
// 올려두면, NPC 대화는 계속 막힌 채 꽃다발만 잡고/들고 있을 수 있다. (대화 시작 시 이미 들고 있던
// 오브젝트가 레이어 차단으로 손에서 떨어지는 것도 막아준다.) 건넸는지 판정은 아이템의 DialogGestureItem이
// NPC의 받는 존(태그) 트리거에 닿는 순수 물리 트리거로 처리하므로 이 블로커와 무관하게 동작한다.
public class DialogInteractionBlocker : MonoBehaviour
{
[Tooltip("차단에서 제외할 인터랙터 (예: 대화 중에도 텔레포트를 허용하고 싶을 때 텔레포트 레이 인터랙터)")]
[SerializeField] private List<XRBaseInteractor> _exclude = new();
[Tooltip("대화 중에도 살려둘 인터랙션 레이어. 여기 든 레이어의 인터랙터블(예: 대화 중 건네야 하는 꽃다발)은 " +
"대화 중에도 잡기/들기가 된다. 비우면(None) 기존처럼 전부 차단")]
[SerializeField] private InteractionLayerMask _keepActiveDuringDialog;
// 차단 직전의 원래 레이어 — 복원용. 비어있지 않으면 차단 중이라는 뜻.
private readonly Dictionary<XRBaseInteractor, InteractionLayerMask> _saved = new();
@@ -43,7 +53,7 @@ private void Block()
{
if (_exclude.Contains(interactor)) continue;
_saved[interactor] = interactor.interactionLayers;
interactor.interactionLayers = 0; // None — 3D 인터랙터블 전부 차단
interactor.interactionLayers = _keepActiveDuringDialog; // 지정 레이어만 유지(비우면 None=전부 차단)
}
}