[RN] Rive로 앱에 생명 불어넣기: 실전 연동 튜토리얼 (feat. 디자인은 돈으로 사자)

Rive를 사용하는 이유와 React Native 연동 핵심 코드 정리. 일주일 삽질 끝에 얻은 '가장 효율적인' 개발 가이드.

Jun Noh

지난 주는 월요일부터 일요일까지 말 그대로 일주일을 통째로 날려버렸다.

물론 중간 중간 밥플의 안드로이드 심사도 확인하고 수정한 것도 좀 있지만, 95%의 시간은 Rive와 포토샵을 배우고, 고작 캐릭터 3개의 애니메이션 샘플을 만들어본다고 썼다.

열심히 잘 만들어 놓고 왜 또 이 글을 쓰냐고?

일주일을 통으로 갈아서 나름 공부도 끝내고 완벽하다고 자신하면서 완성했는데, 완성품을 보고 나니까 이건 백만원을 쓰던 이백만원을 쓰던 외주를 주는게 100% 맞다는 확신이 들었으니까.

분명.. 잘 움직이고 귀엽긴한데… 그 “처음 만들어본 티”가 너무 많이 난다.

이 캐릭터가 앱 메인에서 돌아다니는 순간, 내 앱의 완성도와는 상관 없이 사용자에게 보여지는 앱의 퀄리티는 1/2 토막이 날게 뻔했다.

그래서 Rive로 캐릭터를 디자인하고 애니메이션을 넣는건 전문가에게 맡기고, 난 내가 잘 하는 거나 하려고 마지막으로 글을 쓴다.

Rive의 장점은 무엇인지, 언제, 그리고 어떻게 써야하는 지 정리해보려고 한다.

(돈 주고 맡기더라도 뭘 알아야 부려먹을 거 아닌가?)

1. Rive의 작동 원리: 이건 ‘재생’이 아니라 ‘실행’이다

보통 애니메이션 넣는다고 하면 Lottie(JSON)나 GIF, 심하면 MP4 동영상을 생각하는데, Rive는 근본부터 다르다.

1.1 런타임 렌더링 (Real-time Rendering)

Rive는 픽셀 덩어리(이미지)를 저장하는 게 아니다.

점, 선, 곡선, 색상 같은 수학적 데이터를 저장한다.

앱이 실행되면 Rive Runtime(C++ 엔진)이 이 데이터를 읽어서 매 프레임 실시간으로 그린다.

  • 용량: 압도적으로 작다. 이미지 한 장 들어갈 용량에 애니메이션 전체가 들어간다. 서버 트래픽: 쾌적할게.
  • 해상도: 벡터 기반이라 폰이 아무리 커져도 절대 안 깨진다. 아이패드 대응한다고 @3x 이미지 따로 안 만들어도 된다는 소리다.

1.2 State Machine (상태 머신): 로직을 떠넘기자

이게 진짜 물건이다. 개발자 입장에서 제일 귀찮은 게 애니메이션 제어 로직이다. “점프 버튼 누르면 점프 모션 재생하고, 땅에 닿으면 착지 모션 재생하고…” 이걸 코드로 짜면 if-else 떡칠이 된다.

Rive는 이 로직을 .riv 파일 안에 내장(Internalize) 시킨다.

  • Input: 우리는 그냥 isRunning (Boolean), Jump (Trigger) 같은 신호만 던져주면 된다.
  • Transition: 걷다가 뛸 때 얼마나 부드럽게 섞일지(Blending)는 디자이너가 툴에서 설정한다.

즉, “개발자는 신호만 보내고, 디자이너가 로직을 짠다.” 개발 공수 줄어드는 소리가 들린다. 이게 돈 버는 거다.

2. 기술 비교 분석: 뭘 써야 ‘폼’이 날까?

“유니티 쓰면 안 돼요?” 라고 묻는다면, 앱 하나 띄우는데 로딩 5초 걸리게 하고 싶으면 쓰라고 하겠다. 상황별로 딱 정해준다.

비교 항목Game Engine (Unity/Godot)Sprite (PNG/GIF)Rive (Vector Runtime)
적합한 용도본격적인 게임, 3D 월드레트로 감성고급진 UI, 인터랙티브 캐릭터
용량개무거움 (수십 MB+)무거움 (프레임 $\times$ 해상도)깃털 같음 (수십 KB)
해상도좋음구림 (확대하면 픽셀 깨짐)완벽함 (벡터)
RN 통합지옥 (브릿지 비용 큼)쉬움깔끔함 (라이브러리 우수)
퍼포먼스배터리 살살 녹음메모리 먹는 하마최적화 깡패

PL의 선택 가이드:

  • Game Engine: 앱 메인에 캐릭터 하나 세워두자고 유니티 엔진 올리는 건 미친 짓이다. 파리 하나 잡겠다고 M4 난사할건가?
  • Sprite: 프레임 뚝뚝 끊기는 레트로 감성 노리는 거 아니면 쓰지 마라. 요즘 앱 시장에서 “없어 보인다”.
  • Rive: “깔끔하고 군더더기 없는 애니메이션”, “트랜디하다” 소리 듣고 싶으면 이거다.

3. 왜 이 프로젝트엔 Rive인가?

내가 굳이 일주일을 갈아 넣으며 Rive를 팠던 이유는 ‘Mesh Deformation(메쉬 변형)’ 때문이다.

2D 이미지를 가지고 3D처럼 보이게 만드는 기술인데, 스파인(Spine)이나 라이브2D(Live2D) 같은 게임 전용 툴에나 있는 기능이다. 근데 Rive는 이걸 일반 앱 UI용으로 지원한다.

  • Mesh Deformation: 얼굴 이미지 위에 그물망(Mesh)을 씌우고, 뼈(Bone)를 심어서 고개를 돌릴 때 얼굴을 살짝 찌그러뜨리면 입체감이 확 산다.
  • Blending: 대기 상태에서 터치했을 때, 동작이 뚝 끊기지 않고 물 흐르듯 섞인다. 이게 사용자 경험(UX) 퀄리티를 결정한다.

고객들은 이런 디테일에서 “아, 이 앱 비싼 앱이구나”를 느낀다. (물론 내가 만든 결과물은 불쾌한 골짜기였지만.)

4. React Native 구현 튜토리얼

자, 이제 외주 맡겨서 .riv 파일을 받아왔다고 치자. 혹은 무료 에셋이라도 가져왔다고 가정하자. 이걸 앱에 띄우는 건 개발자 몫이다.

rive-react-native 라이브러리가 꽤 잘 되어 있어서 코드 복붙만 해도 반은 간다.

4.1 설치 및 리소스 관리

npm install rive-react-native
cd ios && pod install

리소스 파일(.riv)은 로컬에 심는 게 정신 건강에 좋다.

  • Android: android/app/src/main/res/raw/character.riv (파일명 소문자 필수. 대문자 쓰면 빌드 터진다.)
  • iOS: Xcode 열고 Drag & Drop (Copy items if needed 체크).

4.2 상호작용 구현 (Copy & Paste)

그냥 재생하는 건 의미 없다. 유저가 만졌을 때 반응해야 Rive를 사용한 의미가 있다고 본다.

import React, { useRef } from 'react';
import { View, TouchableOpacity } from 'react-native';
import Rive, { RiveRef, Fit, Alignment } from 'rive-react-native';

// 파일명과 State Machine 이름은 디자이너에게 꼭 물어볼 것
const RIVE_RESOURCE = 'character'; 
const STATE_MACHINE = 'InteractiveSM'; 

export default function InteractiveCharacter() {
  const riveRef = useRef<RiveRef>(null);

  const handleTouch = () => {
    // 1. Trigger 타입: 한 번 실행 (예: 점프, 깜짝 놀람)
    riveRef.current?.fireState(STATE_MACHINE, 'TriggerJump');
    
    // 2. Boolean 타입: 상태 변경 (예: 화난 표정 유지)
    // riveRef.current?.setInputState(STATE_MACHINE, 'isAngry', true);
  };

  const handleSlider = (val: number) => {
    // 3. Number 타입: 수치 제어 (예: 시선 처리)
    riveRef.current?.setInputState(STATE_MACHINE, 'lookDirection', val);
  };

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <TouchableOpacity onPress={handleTouch}>
        <Rive
          ref={riveRef}
          resourceName={RIVE_RESOURCE}
          stateMachineName={STATE_MACHINE}
          fit={Fit.Cover} // 화면 꽉 차게
          style={{ width: 300, height: 300 }}
          autoplay={true}
        />
      </TouchableOpacity>
    </View>
  );
}

코드는 이게 전부다. 깔끔하지 않나? 복잡한 로직은 다 .riv 파일 안에 있으니까 트리거만 당기면 된다.

5. 요약 및 실전 로드맵

일주일간 직접 부딪혀보고 내린 Rive 도입 최단 경로다.

  1. 기술 검토: 게임 만들 거 아니면 Unity 쳐다보지 마라. 2.5D 인터랙티브는 Rive가 표준이다.

  2. R&R 분배:

    • 디자이너(혹은 외주): .riv 파일 제작, State Machine 로직 설계, Input 이름 정의.
    • 개발자(나): 위 튜토리얼 코드 복붙, fireState 연결, 서버 연동.
  3. 주의사항: 디자이너에게 작업 맡길 때 Input 변수 명세서를 반드시 요구해라. 뭐, 이걸 포함해서, 명세서가 구체적이고 뭘 원하고 있는 지 확실해야. 외주를 받는 입장에서도 편하다.

나는 이제 이 가이드라인 들고 크몽(한국은 거의 없는 거 같다.)이나 Fiverr 뒤지러 가야겠다. 개발자는 코드를 짤 때 가장 효율적이고, 디자인은 전문가가 할 때 가장 아름다운 법이다.

마침. (툴은 죄가 없다. 내 손이 문제지.)

다른 글 보기