Update README.md
This commit is contained in:
34
README.md
34
README.md
@@ -65,43 +65,13 @@
|
|||||||
|
|
||||||
### 5. 카트 시스템
|
### 5. 카트 시스템
|
||||||
<img src="/readme/cart1.png" width="400">
|
<img src="/readme/cart1.png" width="400">
|
||||||
|
<img src="/readme/cart2.png" width="200"> 해당 영역에 아이템이 들어오면,
|
||||||
|
아이템의 움직임이 없어질 때(혹은 0.3초가 지났을 때) 물리영향을 끄고 카트의 움직임을 ‘ParentConstraint’ 로 추적한다.
|
||||||
|
|
||||||
VR에서 "물건을 카트에 담는다"는 단순해 보여도 실제로는 네 가지 문제가 동시에 발생한다. 각 문제를 다음과 같이 해결했다.
|
|
||||||
|
|
||||||
**(1) 플레이어가 카트와 함께 움직이게 만들기 — `ParentConstraint`**
|
|
||||||
- 카트에 `ParentConstraint`를 붙이고 source로 `XROrigin`을 잡음. 결과적으로 **XROrigin(=플레이어)이 카트의 자식처럼 따라다님**.
|
- 카트에 `ParentConstraint`를 붙이고 source로 `XROrigin`을 잡음. 결과적으로 **XROrigin(=플레이어)이 카트의 자식처럼 따라다님**.
|
||||||
- `ActiveRide()` / `DeactiveRide()`로 constraint 활성/비활성 토글 → 카트에서 내릴 때는 constraint만 끊으면 되고, XROrigin 계층은 건드리지 않음.
|
- `ActiveRide()` / `DeactiveRide()`로 constraint 활성/비활성 토글 → 카트에서 내릴 때는 constraint만 끊으면 되고, XROrigin 계층은 건드리지 않음.
|
||||||
|
|
||||||
**(2) 물건이 카트와 같이 안 움직이는 문제 — Reparent + Kinematic**
|
|
||||||
- `Rigidbody` 상태로 바구니에 얹혀 있어도 카트가 움직이면 충돌·관성으로 즉시 튀어나옴.
|
|
||||||
- 정착이 확정되면 `transform.SetParent(_itemRoot)`로 카트 하위에 부착하고 `isKinematic = true`로 전환. 이때부터는 카트의 transform을 그대로 따라가고 물리 시뮬레이션에서 빠짐.
|
|
||||||
|
|
||||||
**(3) 관성으로 물건이 빠져나오는 문제 — 정착 타이머**
|
|
||||||
- 단순히 "트리거 진입 = 부착"으로 하면 던져 넣자마자 위로 튀는 운동량 때문에 카트 밖으로 다시 튀어나감. 게다가 한 번 부착되면 더 이상 던질 수 없음(움직이는 카트 바깥으로 떨어뜨릴 수 없음).
|
|
||||||
- `OnDetectionStay`에서 매 프레임 검사:
|
|
||||||
- `linearVelocity.magnitude > _settleVelocity`(임계 속도)면 타이머 리셋 — 아직 움직이는 중
|
|
||||||
- 임계 속도 이하 상태가 `_settleDuration` 동안 **연속으로 유지**되면 부착 확정
|
|
||||||
- `XRGrabInteractable.isSelected`(현재 손에 잡혀있음)면 타이머 무효화 — 잡고 있는 동안엔 절대 부착되지 않음
|
|
||||||
- `_settleTimer`는 `Dictionary<Rigidbody, float>`로 아이템별 타이머를 독립 관리.
|
|
||||||
|
|
||||||
**(4) 물건 위에 물건을 쌓는 문제**
|
|
||||||
- 위 정착 타이머는 **각 Rigidbody별로** 독립적으로 흐름. 아래 물건이 먼저 정착해 kinematic이 되면, 그 위에 떨어뜨린 물건은 단단한 받침대 위에서 속도가 0에 수렴 → 자기 차례에 정착 → 다음 물건의 받침대가 됨.
|
|
||||||
- 트리거 영역(`RideDetectionZone`)을 카트 바구니보다 충분히 높게 잡아 쌓인 물건도 검사 대상에 포함.
|
|
||||||
|
|
||||||
**(5) 카트에서 다시 꺼낼 때의 함정 — `retainTransformParent` & isKinematic 복원 덮어쓰기**
|
|
||||||
- `XRGrabInteractable`은 **잡힐 때 부모/kinematic 상태를 스냅샷**해 두고, 놓을 때 그 상태로 되돌린다. 카트에서 부착될 때 부모=ItemRoot, kinematic=true로 잡혔으니, 손으로 꺼냈다가 어딘가 놔도 **다시 ItemRoot 자식으로 + kinematic 상태로** 복원되어 공중에 박제되는 버그.
|
|
||||||
- 두 단계로 차단:
|
|
||||||
- 부착 시 `grab.retainTransformParent = false` — 부모 복원 비활성화.
|
|
||||||
- 꺼낼 때 `selectEntered` → 즉시 부모 해제, `selectExited`에서 `isKinematic = false`를 다시 강제로 덮어쓰기.
|
|
||||||
|
|
||||||
```
|
|
||||||
물건 던져넣기 → 트리거 진입 → [속도 < 임계 && 잡혀있지 않음] 0.3s 유지
|
|
||||||
→ SetParent(ItemRoot) + isKinematic=true + retainTransformParent=false
|
|
||||||
→ 카트 이동에 종속
|
|
||||||
|
|
||||||
손으로 다시 잡음 → SetParent(null) → 일반 물리로 복귀
|
|
||||||
→ 놓을 때 isKinematic=false 강제 복원
|
|
||||||
```
|
|
||||||
|
|
||||||
### 6. 씬 전환 라이프사이클
|
### 6. 씬 전환 라이프사이클
|
||||||
- `ITransScenePossible` 인터페이스 — 씬 로드 직후 `OnSceneLoaded()`를 일괄 호출해 **씬을 가로지르는 매니저(GameManager 등)가 새 씬의 매니저(GameSceneUIManager)와 다시 결선**되도록 함. 싱글톤이 죽지 않은 채 새 씬의 UI 참조만 갱신.
|
- `ITransScenePossible` 인터페이스 — 씬 로드 직후 `OnSceneLoaded()`를 일괄 호출해 **씬을 가로지르는 매니저(GameManager 등)가 새 씬의 매니저(GameSceneUIManager)와 다시 결선**되도록 함. 싱글톤이 죽지 않은 채 새 씬의 UI 참조만 갱신.
|
||||||
|
|||||||
Reference in New Issue
Block a user