# 반응 시퀀서와 트리거 WPF 앱은 상황키를 보낸다. Live2D 런타임은 `reactions.json`과 `clips/*.json`을 읽어 motion, expression, mouth/caption, sfx를 실행한다. ## 트리거 매퍼 ```json { "map": { "idle": "idle_dance", "error": "gesture_no", "success": "gesture_heart" } } ``` ## 반응 클립 스키마 ```jsonc { "name": "gesture_heart", "duration": 2.2, "return": "idle", "live2d": { "motion": { "group": "Reaction", "name": "motion_heart", "file": "motions/heart.motion3.json" }, "expression": { "name": "exp_love", "file": "expressions/love.exp3.json" }, "mouth": { "t": 0.5, "say": "잘됐어요", "dur": 1.1, "driver": "volume" }, "caption": { "t": 0.5, "text": "잘됐어요", "dur": 1.5 }, "sfx": { "t": 0.45, "id": "success" } } } ``` ## 런타임 처리 1. WPF가 WebView2에 `{ "type": "react", "key": "success" }` 전송. 2. JS 런타임이 `reactions.json`에서 클립을 선택. 3. `clips/*.json` 로드. 4. Cubism 모델에 motion과 expression 적용. 5. mouth driver가 있으면 `ParamMouthOpenY`를 시간/볼륨에 따라 구동. 6. caption, TTS, sfx를 앱 설정에 따라 표시 또는 재생. 7. 종료 후 idle motion으로 복귀. ## 상황 카탈로그 | 상황키 | 클립 | Motion | Expression | 대사 | |---|---|---|---|---| | `idle` | `idle_dance` | `motion_idle_dance` | `exp_smile` | 없음 | | `error` | `gesture_no` | `motion_no` | `exp_negative` | 안돼요 | | `success` | `gesture_heart` | `motion_heart` | `exp_love` | 잘됐어요 | | `greet` | `gesture_greet` | `motion_greet` | `exp_smile` | 안녕하세요 | | `explain` | `gesture_present` | `motion_present` | `exp_neutral` | 상황별 | | `thinking` | `gesture_thinking` | `motion_thinking` | `exp_thinking` | 없음 | ## WPF API 초안 ```csharp Mascot.SetIdle("idle"); Mascot.React("success"); Mascot.React("error"); Mascot.Say("환영합니다", expression: "exp_smile"); Mascot.SetVisible(true); ``` ## WebView2 메시지 ```json { "type": "react", "key": "success" } { "type": "say", "text": "환영합니다", "expression": "exp_smile" } { "type": "setIdle", "key": "idle" } ```