From f1b68b0e71b80b24f2ef776ea7cd6c3968f61e56 Mon Sep 17 00:00:00 2001 From: nakjun Date: Thu, 25 Jun 2026 17:35:43 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B8=B0=EC=96=B5=EC=9D=98=EC=A1=B0=EA=B0=81?= =?UTF-8?q?=20UI=EB=B2=84=ED=8A=BC=20=EA=B0=84=ED=97=90=EC=A0=81=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=95=88=EB=88=8C=EB=A6=AC=EB=8A=94=20=ED=98=84?= =?UTF-8?q?=EC=83=81=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WhaleAdventure_VR/Rooms/CatsRoom.unity | 4 +- .../02_Scripts/Managers/CollectionManager.cs | 18 +++- Assets/02_Scripts/UI/CollisionButton.cs | 95 +++++++++++++++++++ Assets/02_Scripts/UI/CollisionButton.cs.meta | 2 + Assets/04_Models/VRPlayer.prefab | 4 +- 5 files changed, 118 insertions(+), 5 deletions(-) create mode 100644 Assets/02_Scripts/UI/CollisionButton.cs create mode 100644 Assets/02_Scripts/UI/CollisionButton.cs.meta diff --git a/Assets/01_Scenes/WhaleAdventure_VR/Rooms/CatsRoom.unity b/Assets/01_Scenes/WhaleAdventure_VR/Rooms/CatsRoom.unity index 9eb0c629..1b0105c8 100644 --- a/Assets/01_Scenes/WhaleAdventure_VR/Rooms/CatsRoom.unity +++ b/Assets/01_Scenes/WhaleAdventure_VR/Rooms/CatsRoom.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ce4d73a14aac38dbf339c2dc94f9d445893998cd7bdb20a78bdcd52cb9ef4bb7 -size 2940781 +oid sha256:2383d609077f84049d7a789798d6b1454e399f95a268447b2d9a2c514ea3b6e2 +size 2942559 diff --git a/Assets/02_Scripts/Managers/CollectionManager.cs b/Assets/02_Scripts/Managers/CollectionManager.cs index dc587dd7..7b6850c1 100644 --- a/Assets/02_Scripts/Managers/CollectionManager.cs +++ b/Assets/02_Scripts/Managers/CollectionManager.cs @@ -1,6 +1,6 @@ using UnityEngine; -public class CollectionManager : MonoBehaviour +public class CollectionManager : MonoBehaviour, ISceneInitializable { public static CollectionManager Instance; @@ -28,6 +28,22 @@ void Start() UpdateUI(); } + // SceneLoadManager가 씬 로드마다 호출. 새 씬의 StarPieceHud를 다시 찾아 연결한다. + public void OnSceneLoaded() + { + FindStarPieceHud(); + UpdateUI(); + } + + private void FindStarPieceHud() + { + // 비활성(토글로 꺼진) HUD도 찾을 수 있도록 Include + _starPieceHud = FindFirstObjectByType(FindObjectsInactive.Include); + + if (_starPieceHud == null) + Debug.LogWarning("[CollectionManager] 현재 씬에서 StarPieceHud를 찾지 못했습니다.", this); + } + public void AddStar(int amount) { _currentStars += amount; diff --git a/Assets/02_Scripts/UI/CollisionButton.cs b/Assets/02_Scripts/UI/CollisionButton.cs new file mode 100644 index 00000000..8aafde10 --- /dev/null +++ b/Assets/02_Scripts/UI/CollisionButton.cs @@ -0,0 +1,95 @@ +using UnityEngine; +using UnityEngine.Events; + +/// +/// VR 손이 콜라이더에 닿을(OnTriggerEnter) 때마다 작동하는 버튼. +/// XR UI 포인터/포크 상호작용이 불안정할 때, 트리거 콜라이더로 직접 눌리도록 한다. +/// +[RequireComponent(typeof(Collider))] +public class CollisionButton : MonoBehaviour +{ + [Header("Hand Detection")] + [Tooltip("이 태그를 가진 콜라이더를 손으로 인식합니다.")] + [SerializeField] private string handTag = "PlayerHand"; + + [Tooltip("태그가 달라도 XRHandMarker가 붙어 있으면 손으로 인식합니다.")] + [SerializeField] private bool detectByHandMarker = true; + + [Header("Press Behavior")] + [Tooltip("한 번 눌린 뒤 다시 눌리기까지의 최소 간격(초). 중복/연타 입력을 막습니다.")] + [SerializeField] private float cooldown = 0.4f; + + [Tooltip("꺼두면 손이 닿아도 반응하지 않습니다.")] + [SerializeField] private bool interactable = true; + + [Header("Events")] + [Tooltip("손이 닿아 눌릴 때마다 발생합니다.")] + public UnityEvent onPressed; + + [Header("Debug")] + [SerializeField] private bool showDebugLog = false; + + // timeScale=0(일시정지)에서도 동작하도록 unscaled 시간 사용 + private float _lastPressTime = -999f; + + // 에디터에서 컴포넌트를 처음 추가할 때 콜라이더를 트리거로 자동 설정 + private void Reset() + { + Collider col = GetComponent(); + if (col != null) + col.isTrigger = true; + } + + private void Awake() + { + Collider col = GetComponent(); + if (col != null && !col.isTrigger) + { + col.isTrigger = true; + if (showDebugLog) + Debug.Log("[CollisionButton] Collider가 트리거가 아니어서 강제로 트리거로 설정했습니다.", this); + } + } + + private void OnTriggerEnter(Collider other) + { + if (!interactable) + return; + + if (!IsHand(other)) + return; + + // 양손 콜라이더가 거의 동시에 들어오거나 빠르게 재진입할 때 중복 발동 방지 + if (Time.unscaledTime - _lastPressTime < cooldown) + return; + + Press(); + } + + private void Press() + { + _lastPressTime = Time.unscaledTime; + + if (showDebugLog) + Debug.Log("[CollisionButton] 손이 닿아 버튼이 눌렸습니다.", this); + + onPressed?.Invoke(); + } + + private bool IsHand(Collider other) + { + if (other == null) + return false; + + if (!string.IsNullOrEmpty(handTag) && other.CompareTag(handTag)) + return true; + + if (detectByHandMarker && other.GetComponentInParent() != null) + return true; + + return false; + } + + // 런타임에 활성/비활성 토글이 필요할 때 (UnityEvent 등에서 호출) + public void SetInteractable(bool value) => interactable = value; +} diff --git a/Assets/02_Scripts/UI/CollisionButton.cs.meta b/Assets/02_Scripts/UI/CollisionButton.cs.meta new file mode 100644 index 00000000..fd6433b1 --- /dev/null +++ b/Assets/02_Scripts/UI/CollisionButton.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: c966c32e4e695c44795f9eb58d43d772 \ No newline at end of file diff --git a/Assets/04_Models/VRPlayer.prefab b/Assets/04_Models/VRPlayer.prefab index efc6c6d6..4b9202b9 100644 --- a/Assets/04_Models/VRPlayer.prefab +++ b/Assets/04_Models/VRPlayer.prefab @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0977e7148adf1f7560756d79d82627e84cbcf2a279b94579605dec0d51e16a67 -size 162464 +oid sha256:d8d8dff5e3cd0c29cd86ccb70104c075b598ed1702ad010112c265f06e52ca2b +size 163330