Unity
"로봇이랑 퍼즐 대결하는 게임 만들어주세요" — 그 한마디가 지옥의 시작이었다
김*겸··수정됨 2026.07.21
프로젝트가 뭔데?
인천학생과학관에 설치될 체험형 전시 콘텐츠다. 관람객(주로 학생)이 터치 디스플레이 앞에 서서 퍼즐을 풀고, 바로 옆에 있는 Lebai LM3 협동 로봇이 동시에 움직인다. 로봇이 16세트의 동작을 전부 끝내기 전에 퍼즐을 다 맞추면 사람 승리, 못 맞추면 로봇 승리.
"AI한테 이길 수 있을까?" 라는 호기심을 건드려서 과학 기술에 대한 흥미를 유도하는 게 목적이다.
기술 스택
영역기술게임 엔진Unity 2022+ (URP)언어C# (.NET Standard 2.1)입력Unity New Input System (마우스 + 터치)UIuGUI + TextMesh Pro로봇 통신HTTP POST + JSON-RPC 2.0 (async/await)로봇Lebai LM3 6축 협동 로봇
작업 구조 — 7번의 커밋에 담긴 진화의 역사
1단계: 퍼즐 게임 본체 구현 (Initial commit)
5×5 = 25피스 드래그 앤 드롭
UI 패널 슬라이드 애니메이션
SoundManager, 타이머, 결과 처리
여기까지는 평화로웠다.
2단계: 로봇 연결의 시작 (Lebai 로봇 컨트롤러 기능 추가)
JSON-RPC 2.0으로 로봇과 통신
Connect → start_sys → init_claw 자동 시퀀스
그리퍼 슬라이더, PowerOff 버튼
"오, 로봇이 움직인다!" 하고 좋아한 건 딱 여기까지.
3단계: 티칭 시스템 + 버큠 그리퍼 (티칭 시스템 개선)
move_joint 후 duration 대기 추가 (그리퍼 타이밍 문제 해결)
set_do 액션 타입 추가 (디지털 출력 = 버큠 그리퍼 on/off)
티칭 중 UI 비활성화
함정: 로봇 관절이 움직이는 도중에 그리퍼 명령을 보내면 물건을 놓침. duration만큼 기다려야 한다는 걸 깨닫기까지 수십 번의 시행착오.
4단계: 게임-로봇 연동 (게임-로봇 연동 개선)
게임 모드에서 티칭 UI 팝업 비활성화 (StartTeachingWithoutUI)
로봇 티칭 완료 시 콜백으로 로봇 승리 판정
정리/초기화/티칭 기능 분리
함정: 티칭 테스트용 UI와 게임 중 자동 실행 로직이 서로 간섭. UI 없이 티칭만 돌리는 별도 메서드가 필요했다.
5단계: 타이머 유연화 (타이머 소스 선택 옵션)
로봇 JSON의 totalDuration vs 인스펙터에서 수동 입력
교훈: 로봇이 없는 개발 환경에서 테스트하려면 타이머를 로봇에 의존하면 안 된다.
6단계: 대공사 (게임모드 전면 개편)
단일 티칭 파일 → 개별 16세트 JSON 파일로 분리
터치 입력 드래그 지원 (IDragHandler)
자동 Connect + SecretToggle 개발자 패널
로봇 승리 판정: 타이머 기반 → 로봇 완료 콜백 방식으로 전환
패널 재활성화 시 중복 StartGame 버그 수정
티칭 중 홈 이동 방지 가드 추가
이 커밋 하나가 프로젝트의 50%였다.
힘들었던 것들 (진짜 솔직하게)
1. 로봇은 동기적이고, 게임은 비동기적이다
Unity는 프레임 단위로 돌아가는데, 로봇 API는 HTTP 요청/응답 기반이다. await를 빼먹으면 UI가 멈추고, 너무 남발하면 타이밍이 안 맞는다. 특히 16개 티칭을 순차 실행하면서 동시에 게임 타이머도 돌리고, 유저 입력도 받아야 하는 상황은 비동기 지옥 그 자체.
2. "정리" 로직이 게임보다 어렵다
게임이 끝나면 로봇이 원래 위치로 돌아가야 한다. 근데 승리든 패배든, 도중에 끊기든, 비활성 타임아웃이든 — 어떤 상황에서든 안전하게 돌아가야 한다. 키오스크는 무인 운영이니까. 이걸 빼먹으면 로봇이 퍼즐 조각을 쥔 채로 멈춘다. 전시장에서.
3. 터치 입력은 마우스 입력이 아니다
처음에 마우스 드래그로만 만들어놓고 "터치도 되겠지~" 했다가 낭패. Unity의 IDragHandler를 써서 터치/마우스 통합 처리를 해야 했고, 멀티 터치 방지까지 고려해야 했다.
4. 로봇 타이밍 ≠ 코드 타이밍
JSON에 적힌 duration과 실제 로봇이 움직이는 시간이 미묘하게 다르다. 특히 속도 배율(_speedMultiplier)을 적용하면 계산이 꼬인다. EASY(1배속)에서 잘 되던 게 HARD(2배속)에서 터지는 건 일상이었다.
5. 개발 환경에 로봇이 없다
당연히 집에 6축 협동 로봇이 없다. _fakeCleanupDelay, _developmentMode 같은 디버그 옵션을 만들어서 로봇 없이도 게임 흐름을 테스트할 수 있게 했다. 현장 가서 처음 연결했을 때 한 번에 됐으면 기적이었을 것이다 (안 됐다).
구조적으로 신경 쓴 부분
Assets/Scripts/
├── Manager/ ← GameManager, UIManager, SoundManager (싱글톤)
├── Puzzle/ ← PuzzleManager, PuzzlePiece, PuzzleSlot (게임 로직)
├── Robot/ ← LebaiRobotController (로봇 통신 전담)
├── UI/ ← 버튼 효과, 호버, 디버그 토글
└── Effects/ ← 파티클, 텍스트 웨이브 효과
로봇 티칭 데이터는 StreamingAssets에 JSON으로 분리. Unity 빌드 없이 현장에서 JSON만 수정하면 로봇 동작 조정 가능. 이건 진짜 잘한 선택이었다.
비활성 타이머 30초. 키오스크 앞에서 아이가 가버리면? 자동으로 시작 화면 복귀 + 로봇 홈 복귀. 무인 전시의 핵심.
모든 로봇 통신 로그 기록 (
LebaiRobotLog.txt). 현장에서 문제 생기면 이 로그가 생명줄이다.
배운 것들
하드웨어 연동 프로젝트에서 "나중에 연결하면 되지"는 거짓말이다. 가능하면 빨리, 자주 실물로 테스트하라.
"정상 종료"보다 "비정상 종료 대응"이 더 중요하다. 특히 무인 키오스크에서는.
JSON 기반 설정 분리는 무조건 옳다. 현장에서 빌드를 다시 하는 건 지옥이다.
async/await는 강력하지만, 게임 루프와 섞이면 예상 못한 타이밍 버그가 생긴다.
커밋 메시지는 미래의 나를 위한 편지다. 한 달 뒤에 코드를 봤을 때 "왜 이렇게 했지?"를 커밋 메시지가 답해준다.
마무리
결과물만 보면 그냥 "퍼즐 게임"이다. 근데 이 안에 비동기 로봇 통신, 키오스크 안정성, 터치 입력 처리, 무인 운영 안전장치가 다 들어있다. 보이는 것보다 훨씬 깊은 시스템이고, 만들면서 배운 것도 많았다.
인천학생과학관에 가면 한번 해보세요.
기술 스택: Unity 2022 (URP) / C# / Lebai LM3 / JSON-RPC 2.0
읽기 도구
약 7분 읽기
이 글이 도움이 되었나요?