0%

Unity

양손을 머리 위로 올리고, 제자리에서 통통 뛰면 화면 속 벌이 빠르게 날아가며 안개를 걷어내고 꽃을 피웁니다. 컨트롤러 하나 없이 몸짓만으로 작동하는 전시물

전*원··수정됨 2026.07.21

양손을 머리 위로 올리고, 제자리에서 통통 뛰면 화면 속 벌이 빠르게 날아가며 안개를 걷어내고 꽃을 피웁니다. 컨트롤러 하나 없이 몸짓만으로 작동하는 전시물

이번 포스팅에서는 웹캠 기반 체감형 콘텐츠 '꿀벌 출동! 초록숲 정화 대작전'의 기술적인 구현 과정을 공유합니다.

아키텍처_01_전체구조.png

1. 시스템 아키텍처 개요

본 프로젝트는 크게 세 가지 단계로 구성됩니다.

포즈 인식: 단일 웹캠 영상을 MediaPipe Pose Landmarker 로 분석해, 화면 중앙에 가장 가까운 한 명의 코·어깨·손목 좌표를 매 프레임 추출합니다.

제스처/점프 해석: 양손을 머리 위로 유지한 시간과 코 Y 좌표의 프레임 간 변화량을 각각 '시작 게이지'와 '비행 속도'로 번역하는 상태 머신이 동작합니다.

벌 비행과 정화 연출: 점프 강도로 누적되는 피버 게이지가 스플라인(Spline) 경로 위 벌의 속도, 안개 밀도, 스카이박스(Skybox) 색, 구름 페이드아웃, 꽃 성장까지 하나의 진행도로 동기화합니다.

전체 환경은 Unity 6000.0 과 URP 기반 단일 씬으로 구성되며, 외부 통신 없이 오프라인에서 단독으로 동작합니다.

2. 주요 기술적 구현

2.1 MediaPipe 콜백과 상태 머신 PoseHeadAndGestureController.cs)

OnPoseResult() 콜백은 메인 스레드 경쟁을 피하기 위해 결과를 캐싱만 하고, 실제 해석은 Update() 에서 수행합니다. 상태 머신은 WaitingForUser → WaitingForStartGesture → Running → GameEnd 4단계로, SelectCenterPlayer() 가 코와 양 어깨 평균 위치가 정규화 좌표 (0.5, 0.5) 에 가장 가까운 한 명을 선택합니다. HandleGestureState() 는 손목이 코보다 handAboveHeadOffset(기본 0.05) 만큼 위에 있는 상태가 handsUpDuration 초 유지되면 게임을 시작하고, UpdateJumpSpeed() 는 코의 Y 변화량을 minJumpHeight 노이즈 컷 ~ maxJumpHeight 범위로 정규화해 0~1 의 speedFactor 를 산출합니다.

2.2 게이지-속도 보간과 피버 시스템 BeeOnPathWithPolllen.cs)

벌은 Unity Splines 의 SplineAnimate 가 아닌, manualProgress 값을 매 프레임 splineAnimate.NormalizedTime 에 대입하는 수동 제어 방식으로 움직입니다. 진행 속도는 게이지 0일 때 idleTravelTimeSeconds(100초), 피버 시 feverTravelTimeSeconds(10초) 사이에서 보간됩니다. UpdateFeverState()speedFactorfeverThreshold(0.005) 이상이면 feverChargePerSecond(0.8) 로 게이지를 채우고, 미만이면 feverDecayPerSecond(0.1) 로 천천히 깎아 관람객이 "뛰지 않으면 느려진다"는 즉각적 피드백을 받도록 설계했습니다.

- 게이지 충전 속도: 0.8/초

- 게이지 감소 속도: 0.1/초

- 피버 발동 임계: 게이지 0.8 이상

2.3 진행도에 연동된 환경 정화 연출 BeeOnPathWithPolllen.cs)

같은 클래스의 Update() 는 진행도 0~1 을 기반으로 RenderSettings.fogDensity 를 0.17 에서 0 으로 감소시키고, Skybox 머티리얼의 _Tint / _GroundColor 를 어두운 색에서 밝은 색으로 보간합니다. UpdateGlobalClouds()globalCloudImages[5] 를 이산 임계값(0.1 / 0.3 / 0.5 / 0.7 / 0.8)에서 차례로 비활성화해 하늘이 단계적으로 열리는 감각을 만듭니다. 동시에 FlowerController.csPhysics.OverlapSphere 가 벌 주변 꽃의 ObjectSizeManager.StartIncrease() 를 호출해, 스플라인을 따라 이동하는 벌이 지나는 자리마다 꽃이 자라나도록 연결했습니다.

3. 사용자 경험(UX) 최적화

컨트롤러 없는 시작 제스처 : 양손을 머리 위로 올리는 단순한 동작과 handsUpDuration 동안 차오르는 LoadingBarUI 게이지로, 어린 관람객도 직관적으로 "시작" 을 이해하고 의도하지 않은 오작동을 방지했습니다.

점프가 곧 속도가 되는 체감 루프 : 코 Y 좌표 변화량을 speedFactor 로 매핑하고 피버 게이지로 누적해, 관람객이 뛸수록 벌이 빨라지고 화면이 밝아지는 즉각적 인과 관계를 만들었습니다.

환경 정화 서사 : 안개 밀도 감소, 스카이박스 밝아짐, 구름 다섯 개의 단계적 페이드, 꽃 개화가 모두 동일한 진행도에 동기화되어 "내가 뛰어서 세상이 맑아진다"는 체험 서사를 시각으로 구축했습니다.

전시 운영 안전장치 : 사람 인식이 끊기면 lostTimeout(10초) 뒤 타이틀로 복귀하고, 게임 종료 후 gameEndCooldown(5초) 동안은 다음 사람을 받지 않아 연속 관람 시의 오인식과 의도치 않은 조기 시작을 방지했습니다.

4. 마치며

별도 센서를 몸에 부착하지 않고 웹캠 한 대와 MediaPipe 만으로 체감형 전시를 완성했다는 점이 이 프로젝트의 기술적 핵심입니다. 더 나아가 "점프한다"는 단일 물리 입력을 게이지, 피버, 스카이박스, 꽃 성장이라는 여러 층위의 시각 변화로 직조해, 관람객의 신체 운동이 가상 세계의 정화로 번역되는 구조를 만들었습니다.

향후에는 현재 고정값으로 운영 중인 minJumpHeight 노이즈 컷오프를 현장 조명과 카메라 진동에 맞추어 자동 보정하는 적응형 캘리브레이션을 도입하고, 단일 사용자를 가정한 SelectCenterPlayer 로직을 확장해 두 명 이상의 관람객이 동시에 뛸 때 합산 속도로 함께 비행하는 협동 모드를 추가할 계획입니다.

읽기 도구

6분 읽기

이 글이 도움이 되었나요?

다음으로 읽기