Files
Dansori_Characters/LeeSori_Profile/06_Reactions/Reactions.md
T
2026-07-04 10:34:46 +09:00

3.5 KiB

반응 시퀀서 & 트리거 (Reactions)

상황 → 반응을 정의하는 레이어. 트리거 매퍼(reactions.json) + 반응 클립(clips/*.json)으로 구성.

Phase 2 런타임 구현됨: ../07_Viewer/reactions.html(더블클릭). idle=배경춤(풀캔버스 리그, 허리 봉인 튜닝) + 트리거(idle/error/success). baked 바디 + 표정 머리(목 정합·회전)는 ../../_tools/reactions_layout_render.py_layout.json 사용. head base=sori_head_short. 오프라인 검증 _reaction_preview.png.

트리거 매퍼 (reactions.json)

상황키 → 반응 클립 이름. 앱은 상황키만 던지면 된다.

{ "error": "gesture_no", "success": "gesture_heart", "idle": "dance_idle" }

반응 클립 스키마 (clips/<name>.json)

하나의 반응 = 레이어드 타임라인.

{
  "name": "gesture_no",
  "duration": 2.4,               // 초
  "return": "idle",              // 종료 후 복귀 클립(보통 배경 idle)
  "layers": {
    "body": [                    // Body 트랙: 시간에 따라 rig 클립 or baked 포즈
      { "t":0.0, "mode":"rig",   "clip":"idle" },
      { "t":0.15,"mode":"baked", "image":"sori_body_track_armscross", "fade":0.2 }
    ],
    "face": [                    // 표정 프레임 트랙
      { "t":0.0, "expr":"neutral" },
      { "t":0.3, "expr":"negative" }
    ],
    "mouth": [                   // 말하기(유사 립싱크): expr↔talk 순환
      { "t":0.5, "say":"안돼요", "dur":1.2, "pattern":"talk" }
    ],
    "transform": {               // 리그 위 잔모션(본별 delta) — Animation.md 스키마와 동일
      "head": { "rot":[ {"t":0.5,"v":0},{"t":0.8,"v":9},{"t":1.1,"v":-9},{"t":1.4,"v":9},{"t":1.7,"v":0} ] },
      "chest":{ "ty":[ {"t":0.0,"v":0},{"t":0.2,"v":-4},{"t":0.5,"v":0} ] }
    },
    "caption": [ { "t":0.5, "text":"안돼요", "dur":1.6 } ],   // 옵션 말풍선
    "sfx":     [ { "t":0.5, "id":"nope" } ]                   // 옵션 효과음
  }
}

필드 규칙

  • body[]: 시간순. mode:"rig"+clip 또는 mode:"baked"+image(파일명, 확장자 생략 가능). fade=크로스페이드 초.
  • face[]: expr = 표정 프레임 키(20종 중). 시간에 스냅.
  • mouth[]: say 대사, dur 길이, pattern:"talk"(talk/talk_wide/현재 감정 프레임 순환). 립싱크는 근사.
  • transform: 본별 키프레임(리그 delta). Body가 baked여도 head/chest 등 트랜스폼은 적용(단 baked는 통짜라 파츠 분리 트랜스폼은 제한적 → 주로 전체/머리에 적용).
  • caption/sfx: 옵션. 앱 설정(말풍선/TTS)에 따라 사용.

상황 → 반응 카탈로그

상황키 클립 Body Face Mouth 잔모션
error gesture_no baked armscross negative "안돼요" 고개 젓기
success gesture_heart baked heart love/positive "잘됐어요" 통통 바운스
idle dance_idle rig smile/neutral 그루브 루프
(확장) greet gesture_wave rig wave smile "안녕하세요" 손 흔들기
(확장) explain gesture_present rig present neutral 안내 대사 제시
(확장) thinking gesture_think rig idle_upper thinking 갸웃

트리거 API(개념)

Mascot.React("success")     // reactions.json으로 클립 결정 → 시퀀서 재생 → 종료 후 return 클립
Mascot.SetIdle("dance_idle")// 배경 기본 루프
Mascot.Say("...", expr)     // 임시 대사(mouth+face)만

상세 앱 연동: ../08_Roadmap/App_Integration.md.