Files
WhaleAdventure_VR/Assets/My project/RoomSelect/Scripts/README_KR.md
skrwns304@gmail.com b1e85a5b89 2026-06-19 UI, UI로직
2026-06-19 14:27:40 +09:00

613 lines
14 KiB
Markdown

# 방 선택 UI 스크립트 설명서
이 폴더는 Unity 방 선택 UI에 필요한 기본 스크립트 세트입니다.
목표는 다음 흐름을 만드는 것입니다.
```text
방 버튼 클릭
→ 오른쪽 상세 패널에 방 이름/설명/상태 표시
→ 입장 가능하면 입장하기 버튼 활성화
→ 입장하기 클릭
→ 씬 이동 또는 같은 씬 안에서 플레이어 위치 이동
```
---
## 1. 포함된 스크립트
```text
RoomState.cs
RoomData.cs
RoomButtonUI.cs
RoomDetailUI.cs
RoomSelectManager.cs
RoomEnterHandler.cs
RoomProgressManager.cs
RoomSelectOpenClose.cs
```
처음 테스트에 꼭 필요한 것은 아래 6개입니다.
```text
RoomState.cs
RoomData.cs
RoomButtonUI.cs
RoomDetailUI.cs
RoomSelectManager.cs
RoomEnterHandler.cs
```
추가 기능용 스크립트는 아래 2개입니다.
```text
RoomProgressManager.cs 방 클리어/기억의 조각 조건 관리
RoomSelectOpenClose.cs 방 선택 UI 열기/닫기 관리
```
---
## 2. Unity 폴더 위치
Project 창에 아래 폴더를 만들고 스크립트를 넣으세요.
```text
Assets
└── My project
└── RoomSelect
├── Scripts
├── Data
└── Prefabs
```
스크립트 위치:
```text
Assets/My project/RoomSelect/Scripts
```
방 데이터 asset 위치:
```text
Assets/My project/RoomSelect/Data
```
프리팹 위치:
```text
Assets/My project/RoomSelect/Prefabs
```
---
## 3. Hierarchy 기본 구조
방 선택 UI는 아래 구조를 기준으로 만드세요.
```text
RoomSelectCanvas
└── RoomSelectUI
├── Background
├── TitleText
├── RoomButtonRoot
│ ├── RoomButton_Merchant
│ ├── RoomButton_TruthFountain
│ ├── RoomButton_FairyGarden
│ ├── RoomButton_Workshop
│ ├── RoomButton_CatChoir
│ ├── RoomButton_GhostShip
│ ├── RoomButton_ReverseValley
│ ├── RoomButton_Maze
│ └── RoomButton_FishingSpot
├── DetailPanel
│ ├── RoomNameText
│ ├── RoomDescriptionText
│ ├── RoomStatusText
│ └── EnterButton
│ └── EnterButtonText
├── MemoryProgressArea
└── CloseButton
└── CloseText
RoomEnterSystem
└── RoomEnterHandler
RoomProgressSystem
└── RoomProgressManager
```
---
## 4. 스크립트별 붙이는 위치
| 스크립트 | 붙이는 위치 | 필수 여부 |
|---|---|---|
| `RoomState.cs` | 붙이지 않음 | 필수 |
| `RoomData.cs` | 붙이지 않음, 데이터 asset 생성용 | 필수 |
| `RoomButtonUI.cs` | 각 방 버튼 | 필수 |
| `RoomDetailUI.cs` | `DetailPanel` | 필수 |
| `RoomSelectManager.cs` | `RoomSelectUI` | 필수 |
| `RoomEnterHandler.cs` | `RoomEnterSystem` | 필수 |
| `RoomProgressManager.cs` | `RoomProgressSystem` | 선택이지만 추천 |
| `RoomSelectOpenClose.cs` | `RoomSelectUI` | 선택이지만 추천 |
---
## 5. RoomData asset 만들기
`RoomData.cs`는 ScriptableObject입니다.
씬에 붙이는 스크립트가 아니라, Project 창에서 방 데이터 파일을 만드는 용도입니다.
만드는 방법:
```text
Project 창 우클릭
→ Create
→ Adventure
→ Room Select
→ Room Data
```
9개를 만드세요.
```text
RoomData_Merchant.asset
RoomData_TruthFountain.asset
RoomData_FairyGarden.asset
RoomData_Workshop.asset
RoomData_CatChoir.asset
RoomData_GhostShip.asset
RoomData_ReverseValley.asset
RoomData_Maze.asset
RoomData_FishingSpot.asset
```
---
## 6. RoomData 입력 예시
### 상인의 방
```text
Room Id: Merchant
Room Name: 상인의 방
Description: 수상한 상인이 거래를 제안하는 공간입니다.
Scene Name: MerchantRoom
Required Memory Pieces: 0
Default State: Unlocked
Has Memory Piece Reward: Off
```
### 진실의 샘
```text
Room Id: TruthFountain
Room Name: 진실의 샘
Description: 질문에 따라 피노키오의 코가 반응하는 공간입니다.
Scene Name: TruthFountainRoom
Required Memory Pieces: 0
Default State: Unlocked
Has Memory Piece Reward: On
```
### 요정의 정원
```text
Room Id: FairyGarden
Room Name: 요정의 정원
Description: 푸른 요정의 흔적이 남아 있는 정원입니다.
Scene Name: FairyGardenRoom
Required Memory Pieces: 2
Default State: Locked
Has Memory Piece Reward: On
```
### 제페토의 작업실
```text
Room Id: Workshop
Room Name: 제페토의 작업실
Description: 제페토의 기억과 단서가 남아 있는 작업실입니다.
Scene Name: WorkshopRoom
Required Memory Pieces: 3
Default State: Locked
Has Memory Piece Reward: On
```
### 냥아치들의 섬
```text
Room Id: CatChoir
Room Name: 냥아치들의 섬
Description: 고양이 합창단과 함께 리듬게임을 진행하는 공간입니다.
Scene Name: CatChoirRoom
Required Memory Pieces: 0
Default State: Unlocked
Has Memory Piece Reward: On
```
### 저주받은 난파선
```text
Room Id: GhostShip
Room Name: 저주받은 난파선
Description: 유령 선장과 블랙잭 게임을 벌이는 위험한 난파선입니다.
Scene Name: GhostShipRoom
Required Memory Pieces: 1
Default State: Locked
Has Memory Piece Reward: On
```
### 거꾸로 계곡
```text
Room Id: ReverseValley
Room Name: 거꾸로 계곡
Description: 조작 방향이 반대로 바뀌는 이상한 공간입니다.
Scene Name: ReverseValleyRoom
Required Memory Pieces: 2
Default State: Locked
Has Memory Piece Reward: On
```
### 별빛 미로
```text
Room Id: Maze
Room Name: 별빛 미로
Description: 나침반의 도움을 받아 출구를 찾아야 하는 미로입니다.
Scene Name: MazeRoom
Required Memory Pieces: 3
Default State: Locked
Has Memory Piece Reward: On
```
### 기묘한 낚시터
```text
Room Id: FishingSpot
Room Name: 기묘한 낚시터
Description: 낚시와 정화를 통해 단서를 얻는 공간입니다.
Scene Name: FishingSpotRoom
Required Memory Pieces: 0
Default State: Unlocked
Has Memory Piece Reward: On
```
---
## 7. RoomButtonUI 연결 방법
각 방 버튼에 `RoomButtonUI.cs`를 붙입니다.
예:
```text
RoomButton_Merchant
└── RoomButtonUI
```
Inspector 연결:
```text
Room Data → RoomData_Merchant.asset
Button → 자기 자신의 Button 컴포넌트
Background Image → 자기 자신의 Image 컴포넌트
Room Icon Image → RoomIcon이 있으면 연결, 없으면 비워둠
Room Name Text → RoomNameText
Lock Icon → LockIcon
Clear Icon → ClearIcon
```
상태별 Sprite가 아직 없다면 비워둬도 됩니다.
Sprite가 없으면 스크립트가 Color로 버튼 상태를 표시합니다.
---
## 8. RoomDetailUI 연결 방법
`DetailPanel``RoomDetailUI.cs`를 붙입니다.
```text
DetailPanel
└── RoomDetailUI
```
Inspector 연결:
```text
Room Name Text → DetailPanel/RoomNameText
Room Description Text → DetailPanel/RoomDescriptionText
Room Status Text → DetailPanel/RoomStatusText
Enter Button → DetailPanel/EnterButton
Enter Button Text → DetailPanel/EnterButton/EnterButtonText
```
방을 선택하면 이 패널에 방 정보가 표시됩니다.
---
## 9. RoomSelectManager 연결 방법
`RoomSelectUI``RoomSelectManager.cs`를 붙입니다.
```text
RoomSelectUI
└── RoomSelectManager
```
Inspector 연결:
```text
Room Buttons Size: 9
Element 0 → RoomButton_Merchant의 RoomButtonUI
Element 1 → RoomButton_TruthFountain의 RoomButtonUI
Element 2 → RoomButton_FairyGarden의 RoomButtonUI
Element 3 → RoomButton_Workshop의 RoomButtonUI
Element 4 → RoomButton_CatChoir의 RoomButtonUI
Element 5 → RoomButton_GhostShip의 RoomButtonUI
Element 6 → RoomButton_ReverseValley의 RoomButtonUI
Element 7 → RoomButton_Maze의 RoomButtonUI
Element 8 → RoomButton_FishingSpot의 RoomButtonUI
Detail UI → DetailPanel의 RoomDetailUI
Room Enter Handler → RoomEnterSystem의 RoomEnterHandler
Room Progress Manager → RoomProgressSystem의 RoomProgressManager
```
`Auto Find Buttons In Children`를 켜면 자식에 있는 `RoomButtonUI`들을 자동으로 찾습니다.
그래도 처음에는 직접 연결하는 것을 추천합니다.
---
## 10. RoomEnterHandler 연결 방법
빈 오브젝트를 만들고 `RoomEnterHandler.cs`를 붙입니다.
```text
RoomEnterSystem
└── RoomEnterHandler
```
### 방식 A: 씬 이동 방식
각 방이 별도 씬이라면:
```text
Use Scene Loading: On
```
그리고 각 `RoomData``Scene Name`에 씬 이름을 넣습니다.
주의:
```text
File → Build Settings → Scenes In Build
```
여기에 씬들이 등록되어 있어야 `SceneManager.LoadScene()`이 정상 작동합니다.
### 방식 B: 같은 씬 안에서 위치 이동 방식
VR 테스트 초반에는 이 방식을 추천합니다.
```text
Use Scene Loading: Off
Player Root → XR Origin 또는 플레이어 루트 오브젝트
Deactivate Other Room Roots → 필요하면 On
Room Targets Size → 방 개수만큼 추가
```
Room Target 예시:
```text
Element 0
Room Id → CatChoir
Spawn Point → CatChoirSpawnPoint
Room Root → Room_CatChoir
Element 1
Room Id → FishingSpot
Spawn Point → FishingSpotSpawnPoint
Room Root → Room_FishingSpot
```
중요:
```text
Room Target의 Room Id는 RoomData의 Room Id와 정확히 같아야 합니다.
```
---
## 11. RoomProgressManager 연결 방법
빈 오브젝트를 만들고 `RoomProgressManager.cs`를 붙입니다.
```text
RoomProgressSystem
└── RoomProgressManager
```
Inspector에서:
```text
Current Memory Pieces → 현재 기억의 조각 개수
Room Progress Entries → 처음에는 비워둬도 됨
```
방 선택 UI는 `Current Memory Pieces``RoomData.Required Memory Pieces`를 비교해서 잠금 여부를 계산합니다.
예:
```text
Current Memory Pieces = 0
GhostShip Required Memory Pieces = 1
→ 저주받은 난파선 잠김
Current Memory Pieces = 1
GhostShip Required Memory Pieces = 1
→ 저주받은 난파선 입장 가능
```
기존 `MemoryProgressManager`를 쓰고 있다면, 해당 매니저의 진행도 변경 이벤트에서 아래 함수를 연결하면 됩니다.
```text
RoomProgressManager.SetMemoryPieceCount(int current, int max)
```
또는 `RoomSelectManager`에 직접 연결해도 됩니다.
```text
RoomSelectManager.SetCurrentMemoryPieces(int current, int max)
```
---
## 12. RoomSelectOpenClose 연결 방법
`RoomSelectUI``RoomSelectOpenClose.cs`를 붙입니다.
```text
RoomSelectUI
└── RoomSelectOpenClose
```
Inspector 연결:
```text
Room Select Root → RoomSelectUI
Room Select Manager → RoomSelectUI의 RoomSelectManager
Target Camera → Main Camera 또는 XR Camera
Open On Start → 테스트할 때는 On, 나중에는 Off
Place In Front Of Camera On Open → On
Face Camera On Open → On
Distance From Camera → 2.2
Vertical Offset → -0.1
```
닫기 버튼 연결:
```text
CloseButton OnClick
→ RoomSelectUI
→ RoomSelectOpenClose.Close()
```
지도 오브젝트 상호작용 연결:
```text
WhaleMapObject Interact()
→ RoomSelectUI
→ RoomSelectOpenClose.Open()
```
---
## 13. 테스트 순서
1. 스크립트를 `Assets/My project/RoomSelect/Scripts`에 넣습니다.
2. `RoomData` asset 9개를 만듭니다.
3. 각 방 버튼에 `RoomButtonUI`를 붙이고 `RoomData`를 연결합니다.
4. `DetailPanel``RoomDetailUI`를 붙이고 텍스트/버튼을 연결합니다.
5. `RoomSelectUI``RoomSelectManager`를 붙이고 버튼 배열, Detail UI, Enter Handler를 연결합니다.
6. `RoomEnterSystem``RoomEnterHandler`를 붙입니다.
7. Play를 누릅니다.
8. 방 버튼을 클릭합니다.
9. 오른쪽 설명 패널이 바뀌는지 확인합니다.
10. 입장 가능한 방에서 `입장하기`를 누릅니다.
11. Console에 `방 입장` 로그가 뜨면 성공입니다.
---
## 14. 자주 생기는 문제
### 버튼을 눌러도 반응이 없음
확인할 것:
```text
씬에 EventSystem이 있는가?
Canvas에 Graphic Raycaster가 있는가?
Button 컴포넌트가 있는가?
RoomButtonUI의 Manager가 자동 또는 수동으로 연결되었는가?
Button Image의 Raycast Target이 켜져 있는가?
```
### 입장 버튼이 안 켜짐
확인할 것:
```text
RoomData.Required Memory Pieces가 너무 높지 않은가?
RoomProgressManager.Current Memory Pieces가 부족하지 않은가?
RoomData.Default State가 Locked로 되어 있지 않은가?
```
### 잠금 해제가 안 됨
확인할 것:
```text
RoomSelectManager의 Room Progress Manager가 연결되어 있는가?
RoomProgressManager.Current Memory Pieces 값이 증가했는가?
RoomSelectManager.RefreshAll()이 호출되었는가?
```
### 씬 이동이 안 됨
확인할 것:
```text
RoomEnterHandler.Use Scene Loading이 On인가?
RoomData.Scene Name이 정확한가?
Build Settings의 Scenes In Build에 해당 씬이 등록되어 있는가?
```
### 같은 씬 이동이 안 됨
확인할 것:
```text
RoomEnterHandler.Use Scene Loading이 Off인가?
Player Root가 연결되어 있는가?
Room Targets의 Room Id가 RoomData.Room Id와 같은가?
Spawn Point가 연결되어 있는가?
```
---
## 15. 추천 개발 순서
처음에는 복잡한 잠금/이동 기능보다 UI 반응부터 확인하세요.
```text
1. 방 버튼 클릭 → 상세 패널 변경 확인
2. 입장 버튼 클릭 → Console 로그 확인
3. RoomProgressManager로 잠금 상태 확인
4. 기억의 조각 개수 변경 → 잠금 해제 확인
5. 같은 씬 안에서 플레이어 위치 이동 연결
6. 나중에 필요하면 씬 이동 방식 연결
```
---
## 16. 완성 후 프리팹 저장
완성되면 아래 오브젝트를 Project 창으로 드래그해서 프리팹으로 저장하세요.
```text
RoomSelectUI
```
저장 위치:
```text
Assets/My project/RoomSelect/Prefabs/UI_RoomSelect.prefab
```
방 버튼 하나도 따로 프리팹으로 저장하면 좋습니다.
```text
Assets/My project/RoomSelect/Prefabs/UI_RoomButton.prefab
```