스마트싱스SmartThings 접근성 향상과 ‘띵구’들과의 소통을 위한 스마트 홈의 또다른 해석!
3D room 안의 오브젝트들로 직관적으로 IoT 기기들을 제어하는 나만의 가상 공간, ThingDong 🔔

- 기간 : 2023. 10. 10 ~ 2023. 11. 17 (6주)
- 인원 : 6명
- 역할 : 프론트엔드 팀장 👑
- 수상 : SSAFY 자율 프로젝트 우수상 🥈
- 기술 :
React React Native Three.js React-Three-Fiber(R3F) Jotai TypeScript Styled-Component React-Query
- 협업/상태관리 툴 :
Jira Gitlab Notion
- 링크 : https://github.com/baebaemin/ThingDong
구현 및 기여 영역
랜딩 페이지
스플래시 페이지
메인 화면
- R3F(React-Three-Fiber)로 3D룸 구현, 렌더링
- 3D룸 가구 배치시 오브젝트 종류별 이동 로직 개발
- 가구 배치 종류, 위치, 벽 색상, 라이트/다크 모드 등 3D룸 상태 데이터 바인딩
스마트싱스 연동
- 현실의 기기 상태를 호출하여 3D룸 오브젝트에 반영
- 3D룸의 오브젝트 조작시 현실의 IoT 기기 상태 조작 연동
- ‘띵즈’ 페이지에서 전구 색상 변경시 현실의 스마트전구에 반영
띵구(친구)네 놀러가기
- 띵구 3D룸 상태 데이터 바인딩
- 방명록 작성, 열람, 삭제
하이브리드 앱
기타
- 프론트엔드 팀 리딩
- UX/UI 디자인
- 스타일 가이드 수립
- Spline을 활용한 랜딩 & 스플래시 페이지의 인터랙티브 백그라운드 화면 생성
메인 기능
![[기기 제어 :: 전구] 3D룸 안의 조명의 ON/OFF 상태가 현실의 스마트싱스 조명과 연동됩니다.](https://prod-files-secure.s3.us-west-2.amazonaws.com/aa21ce0f-d1c4-4890-8954-8d097779730a/4d2d75a0-a725-44b9-aad0-eba2f3ba7b0c/bulb_off_and_on_1.gif)
[기기 제어 :: 전구] 3D룸 안의 조명의 ON/OFF 상태가 현실의 스마트싱스 조명과 연동됩니다.
![[기기 제어 :: 커튼] 3D룸 안의 커튼의 열림/닫힘 상태가 현실의 스마트싱스 커튼과 연동됩니다.](https://prod-files-secure.s3.us-west-2.amazonaws.com/aa21ce0f-d1c4-4890-8954-8d097779730a/5dfbab2f-7a60-45b9-a63c-1764093623fc/curtain_on_1.gif)
[기기 제어 :: 커튼] 3D룸 안의 커튼의 열림/닫힘 상태가 현실의 스마트싱스 커튼과 연동됩니다.
![[기기 제어 :: 스위치] 3D룸 안의 스위치의 ON/OFF 상태가 현실의 형광등 스위치와 연동됩니다.](https://prod-files-secure.s3.us-west-2.amazonaws.com/aa21ce0f-d1c4-4890-8954-8d097779730a/ecd863c6-33d5-4614-99e4-f8adbf4b8785/switch_on_1.gif)
[기기 제어 :: 스위치] 3D룸 안의 스위치의 ON/OFF 상태가 현실의 형광등 스위치와 연동됩니다.
![[스마트싱스 연동] 삼성 계정 로그인 및 PAT(Personal Access Token) 발급으로 기기를 불러옵니다.](https://prod-files-secure.s3.us-west-2.amazonaws.com/aa21ce0f-d1c4-4890-8954-8d097779730a/ac6eb0e6-a890-455f-b49b-f3203e810761/08_things_1.gif)
[스마트싱스 연동] 삼성 계정 로그인 및 PAT(Personal Access Token) 발급으로 기기를 불러옵니다.
![[방 꾸미기] 띵Thing으로 구매한 아이템들과 불러온 띵즈(스마트싱스 기기)로 나만의 방을 꾸며보세요.](https://prod-files-secure.s3.us-west-2.amazonaws.com/aa21ce0f-d1c4-4890-8954-8d097779730a/b95b8395-a292-45a6-ac56-4721131ca120/11_change_my_room_2.gif)
[방 꾸미기] 띵Thing으로 구매한 아이템들과 불러온 띵즈(스마트싱스 기기)로 나만의 방을 꾸며보세요.
![[방 꾸미기] 라이트모드, 다크모드 설정과 벽지 & 배경 색상을 취향대로 설정할 수 있습니다.](https://prod-files-secure.s3.us-west-2.amazonaws.com/aa21ce0f-d1c4-4890-8954-8d097779730a/f3afd0b2-a13d-417e-87b8-69148cb649bd/03_change_room_color_2.gif)
[방 꾸미기] 라이트모드, 다크모드 설정과 벽지 & 배경 색상을 취향대로 설정할 수 있습니다.
![[띵구네 놀러가기] 서로의 방에 놀러가 방명록도 남기고, 어떤 IoT 기기를 쓰는지 구경과 구매도 할 수 있어요.](https://prod-files-secure.s3.us-west-2.amazonaws.com/aa21ce0f-d1c4-4890-8954-8d097779730a/32f3f892-0f09-49cd-83b3-c64bc7954064/05_thinggu_room_1.gif)
[띵구네 놀러가기] 서로의 방에 놀러가 방명록도 남기고, 어떤 IoT 기기를 쓰는지 구경과 구매도 할 수 있어요.
![[인벤토리] 띵Thing으로 아이템을 구매하고, 보유한 아이템들과 불러온 띵즈들의 목록을 확인합니다.](https://prod-files-secure.s3.us-west-2.amazonaws.com/aa21ce0f-d1c4-4890-8954-8d097779730a/bf563627-fcab-4690-8204-bf79a4dbbca8/09_inventory.gif)
[인벤토리] 띵Thing으로 아이템을 구매하고, 보유한 아이템들과 불러온 띵즈들의 목록을 확인합니다.
![[언박띵] Text-To-3D 생성 모델을 활용해 직접 텍스트를 입력하여 나만의 특별한 오브젝트를 만들어보세요.](https://prod-files-secure.s3.us-west-2.amazonaws.com/aa21ce0f-d1c4-4890-8954-8d097779730a/67c11932-8f06-41f5-8d0e-ccee55b7e156/10_unboxthing_2.gif)
[언박띵] Text-To-3D 생성 모델을 활용해 직접 텍스트를 입력하여 나만의 특별한 오브젝트를 만들어보세요.
챌린지 & 성장
Three.js와 R3F로 구현하는 인터랙티브 3D 웹
- 기획 및 화면 설계, 인터페이스 구현이 끝난 후 9일이라는 짧은 기간 내에 3D룸을 구현해야했습니다.
- Three.js를 처음부터 학습하여 가구 객체 하나하나를 직접 모델링하기엔 시간이 부족하였기에 우선 Spline이라는 인터랙티브 웹 3D 모델 디자인 툴을 활용했습니다. 랜딩 페이지 Opening Scene을 구현할 땐 Spline의 프로젝트 url을 활용하여 import하는 형식으로 렌더링했으며 이를 통해 Canvas, Camera, Renderer 등 Three.js의 기초 설정을 습득하였습니다. 하지만 결국 유저가 조작 가능한 방의 객체들을 구현하기 위해선 glb 또는 gltf 형식의 3D 모델을 로딩하고 렌더링해 화면의 특정 좌표에 배치해야 했습니다.
- 따라서 우선 배치할 가구 종류 및 카테고리를 선정한 후, 7-80여개의 파일을 Unreal Engine과 Spline을 활용하여 glb파일로 추출했습니다. 이어 gltfLoader를 활용하여 오브젝트를 불러와 mesh, material, texture, skin, skeleton 등을 렌더링하는 방법과 관련 옵션들을 학습했습니다. 이때 React-Three-Fiber를 적극적으로 활용하기 시작하였으며, 재사용 가능한 자체 Scene을 선언적으로 구축하도록 도와준다는 점에서 Three.js를 사용하는 것보다 훨씬 편리했습니다.
3D 룸 구현 : 함께하는 데이터 구조 설정과 가구 배치
- 메인 화면에서 렌더링할 3D룸의 데이터는 꽤 복잡한 편이었습니다. 가구 종류, 모델 id, 배치된 위치, 방의 색상, 라이트/다크 모드, 스마트싱스 기기 여부, 작동 상태, 벽 또는 바닥 객체 판별 등 API 호출을 통해 fetching해야 할 정보가 많았습니다. TypeScript를 통한 효율적이고 엄격한 타입 관리를 위해 적극적으로 백엔드 팀에 의견을 제시하여 API 설계 및 수정을 함께 진행했습니다. 이를 바탕으로 띵구(친구)네 방에 방문했을 땐 해당 띵구의 userId만 간단히 바꿔 ‘MyRoomPage’를 렌더링할 때 사용했던 동일한 ‘Room’ 컴포넌트를 재사용할 수 있었습니다.
- 방 배치 기능을 구현할 때 벽걸이 객체와 바닥에 놓이는 객체의 이동 및 회전 로직을 케이스별로 다르게 작성해야 했습니다. 로직을 구현하는 과정에서, 코드를 간결하게 작성하는 것과 팀원이 이해하기 쉽게 하드코딩에 가깝게 작성하는 것 사이에서의 균형을 찾아야 했습니다. 고민끝에 결국 팀원의 이해를 우선시하는 방향을 선택했지만, 코드 개선과 동시에 가독성을 잃지 않는 방법에 대한 고민은 리팩토링과 함께 여전히 지속되고 있습니다.