# 방 선택 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 ```