---

# biped-initial-setup

> slug: biped-initial-setup

3ds Max에서 리깅을 시작할 때 가장 먼저 만나는 Biped, 하지만 기본 설정 그대로 사용하면 나중에 엔진 단계에서 큰 어려움을 겪을 수 있습니다. 안정적인 파이프라인을 위해 아래 설정들을 꼭 확인해 주세요.

## 1. 계층 구조의 논리적 오류 수정

![image.png](biped-initial-setup/image.png)

Biped의 초기 관절 구조는 과거의 스키닝 방식에 맞춰져 있어, 현대적인 엔진 환경에서는 다소 비논리적인 구조를 가지고 있습니다.

- **문제점:** 기본 설정에서는 `Thigh`(허벅지)가 `Spine`(척추) 아래에, `Clavicle`(쇄골)이 `Neck`(목) 아래에 종속되는 경우가 생깁니다.
- **발생하는 이슈:** 엔진에서 캐릭터가 고개를 돌리거나 척추를 보정하는 애니메이션 기능을 넣을 때, 척추를 움직였는데 다리가 따라 움직이는 등 구조가 아주 복잡하게 꼬여버립니다.

### ✅ 필수 체크 사항 (Figure Mode)

![image_1.png](biped-initial-setup/image_1.png)

![image_2.png](biped-initial-setup/image_2.png)

리깅 셋업 전, **Figure Mode**에서 다음 두 가지를 반드시 설정해 주세요.

- **Triangle Pelvis (삼각형 골반):** 반드시 **체크** (다리 계층 구조를 골반에 올바르게 귀속시킵니다.)
- **Triangle Neck (삼각형 목):** 반드시 **체크 해제** (쇄골과 목의 계층 구조를 논리적으로 분리합니다.)

---

## 2. 정확한 피벗(Pivot) 확인을 위한 모드 변경

![image_3.png](biped-initial-setup/image_3.png)

정교한 리깅을 위해서는 뼈대의 중심점을 정확히 파악하는 것이 중요합니다.

- **Body Type을 [Classic]으로 변경:** Biped를 Box 형태로 바꿀 때, 가장 정확한 피벗 위치를 시각적으로 확인할 수 있는 모드입니다.
- **Box Mode 활성화:** 전체 Biped를 선택한 후 박스 모드를 켜주시면 작업 효율이 훨씬 높아집니다.

---

## 3. 프로덕션 표준 링크 설정 (추천)

프로젝트마다 상이할 수 있지만, 일반적으로 가장 안정적인 데이터 값을 추천해 드립니다. 셋업 작업 진행 시 참고해 보세요.

| **항목** | **권장 설정값** | **비고** |
| --- | --- | --- |
| **Spine Links (척추)** | **3개** | 가장 자연스러운 굴곡을 표현합니다. |
| **Fingers (손가락 개수)** | **5개** | 인간형 캐릭터 표준 |
| **Finger Links (마디)** | **3개** | 실제 손가락 관절 구조와 동일 |
| Porp | 1개 | Biped용 프랍 |

---

**안내해 드린 설정을 완료하셔야 나중에 엔진에서 애니메이션 후보정 작업을 할 때 TA팀과 엔진팀의 고생을 덜어줄 수 있답니다.**
@@

---

# rigging-master-path-setup

> slug: rigging-master-path-setup

https://youtu.be/nSFv1HpeLnY?si=UeQmRehROsrS2ifj

# 3ds Max 리깅 마스터 경로 설정 가이드 - 프로젝트 구조 세팅법

# 🗂️ 갖춰야 하는 작업 환경

> Fast Ref를 100% 활용하기 위한 파이프라인 구축 제안

### 0. 레퍼런스 파이프라인 안내 (Best Practice)

기본적으로 리깅 원본과 애니메이션 데이터는 아래와 같이 분리하여 관리하는 것이 정석입니다.

| **구분** | **리깅 원본 (Rig)** | **애니메이션 파일 (Ani)** |
| --- | --- | --- |
| **애니메이션 데이터** | **X (Empty)** | **O (Data Included)** |
| **리깅 링크 상태** | 원본 파일 | 리깅 파일이 **Link**된 상태 |

> 💡 안내: 다만, 3ds Max 기반의 게임 애니메이션 제작 환경 특성상, 이러한 레퍼런스 기반 파이프라인 방식이 다소 생소하거나 기존 작업 방식과 차이가 있을 수 있습니다. 이는 효율적인 협업을 위한 구조이므로 아래 해결 방안을 참고해 주시기 바랍니다.

![image.png](rigging-master-path-setup/image.png)

## 1️⃣ 팀 공유 드라이브 환경 구축

### 권장 사항

- **NAS** 또는 **가상 드라이브**를 이용하여 팀 내 **공유용 드라이브** 설치
- 예: `N:\` 드라이브, `Z:\` 드라이브 등

### ⚠️ NAS 추천 이유

| 방식 | 장단점 |
| --- | --- |
| **NAS (권장)** | ✅ 동기화 빠름, SSD 기반 장비 많음 |
| 구글 드라이브 | ❌ 동기화 느림 → 작업 지장 |

---

## 2️⃣ 리깅 마스터 데이터 구조

### 핵심 원칙

> "리깅용 마스터 폴더"를 별도로 만들고,
> 팀 내 애니메이션 작업 시 반드시 해당 경로의 파일만 불러오기

### 📁 권장 폴더 구조

```
project_name (영어 권장)
│
└── rig
    │
    └── lilly (캐릭터명)
        │
        ├── lilly_rig.max        ← 🎯 마스터 파일 (현재 최신)
        │
        ├── texture/             ← 텍스처 폴더
        │   └── 이미지들...      ← ⚠️ 반드시 상대 경로로 연결!
        │
        └── old/                 ← 백업 폴더
            ├── lilly_000_rig.max
            ├── lilly_001_rig.max
            └── ...              ← 자유롭게 작업 데이터 백업
```

### 🎯 핵심 포인트

| 항목 | 설명 |
| --- | --- |
| **마스터 파일** | 항상 최신 리그만 루트에 위치 |
| **old 폴더** | 이전 버전 백업용 |
| **texture** | 상대 경로 연결 필수! |

---

## 3️⃣ 경로 규칙 (매우 중요! ⚠️)

### ❌ 절대 금지

```
C:\프로젝트\캐릭터\릴리_리그.max     ← 한글 경로 ❌
C:\project (복사본)\rig\lilly.max   ← 특수문자 ❌
```

### ✅ 권장

```
C:\project_present\rig\lilly\lilly_rig.max  ← 영어만 ✅
```

### 🤔 왜 한글 경로가 안 되나요?

```
Python 스크립트 사용 시 인코딩 문제 발생!

문제:
  - UTF-8 vs CP949 등 프로그램마다 문자 처리 방식이 다름
  - 경로 인식 실패 → 오류 발생 확률 ↑↑

결론:
  - 파이프라인 자동화를 위해 영어 경로 필수!
```

---

## 4️⃣ 데이터 정리 권장

### 현재 상태 (추정)

- 애니메이션 폴더에 리깅 데이터가 섞여 있음
- 어떤 파일이 최신인지 파악 어려움

### 정리 방향

```
Before:
  animation/
    ├── shot_001.max
    ├── lilly_rig_v3.max      ← 리깅 파일이 섞여있음
    └── shot_002.max

After:
  rig/                        ← 리깅 전용
    └── lilly/
        └── lilly_rig.max

  animation/                  ← 애니메이션 전용
    ├── shot_001.max          ← Fast Ref로 리그 연결
    └── shot_002.max
```

---

## 5️⃣ 팀 내 규칙 준수 (초기 적응)

### 실행 방안

- 처음에는 다소 불편할 수 있음
- **최소 1개월**은 이 규칙을 엄격히 준수
- 이후 문화로 자리잡음

### 📊 실제 사례 (Blender 기반 회사)

```
적용 기간: 1~2개월

결과:
  ✅ "리깅 동기화" 파이프라인 문화 정착
  ✅ 애니메이션 작업 생산성 향상
  ✅ 혼선 현저히 개선 (약 15% 이상)
```

---

## 📋 체크리스트

```
□ 팀 공유 드라이브 설정 (NAS 권장)
□ 리깅 마스터 폴더 구조 생성
□ 기존 데이터 정리 (날 잡아서)
□ 경로 규칙 공유 (한글 금지!)
□ 1개월 규칙 준수 약속
```

---

> "이러한 파이프라인 구축이 장기적으로 작업 효율화에 큰 도움이 될 것입니다!" 🚀
@@

---

# naming-convention-guide

> slug: naming-convention-guide

리깅과 애니메이션 파이프라인에서 일관된 네이밍 규칙은 단순한 약속을 넘어, 프로젝트의 안정성을 결정짓는 핵심 요소입니다.

## 1. 네이밍 규칙의 중요성

자동화 시스템과 효율적인 협업을 위해 프로젝트별 규칙 준수는 필수적입니다. 예를 들어, 엔진팀에서 `Root` 본을 기준으로 시스템을 구축했는데 데이터가 `root`나 `world`처럼 임의의 이름으로 들어오게 되면, 전체 파이프라인에 큰 차질이 생길 수 있습니다.

## 2. 네이밍의 기본 구성 요소

- **Prefix (접두어):** 이름 앞에 붙여 오브젝트의 성격(Control, Skin 등)을 규정합니다.
- **Suffix (접미어):** 이름 뒤에 붙여 방향(L, R)이나 상태를 표시합니다.

## 3. 주요 네이밍 용법 (Naming Case)

프로젝트의 성격에 따라 적절한 용법을 선택하여 사용합니다.

- **Pascal Case:** `RootNode` (각 단어의 첫 글자를 대문자로 표기)
- **Snake Case:** `root_node` (단어 사이를 언더바`_`로 연결)
- **Camel Case:** `rootNode` (첫 단어는 소문자, 이후 단어 첫 글자 대문자)

## 4. 3ds Max Biped 구조의 이해와 분석

3ds Max의 표준인 Biped(`Bip001 L Foot`)를 유심히 살펴보면, 우리는 중요한 규칙을 발견할 수 있습니다.

> **"아하! 3ds Max에서는 기본적으로 Pascal Case를 기반으로 하고, 단어를 나눌 때 공백(" ")을 사용하고 있구나!"**

숙련된 작업자라면 기존 데이터를 보고 이처럼 **{타입} {방향} {부위}** 규칙을 유추해낼 수 있어야 합니다. 새로운 프로젝트에 참여하더라도 이러한 흐름을 존중하여 작업하는 유연함이 필요합니다.

## 5. 실무 권장 사항: 공백 지양 및 언더바(`_`) 사용

기존 Biped 데이터에는 공백(Space)이 포함된 경우가 많지만, 현대적인 파이프라인에서는 **언더바(`_`)** 사용을 강력히 권장합니다.

- **원인:** 공백은 Maya와의 호환성 문제, 엔진 이관 시 특수문자 치환 오류 등으로 변환되거나, 스크립트 실행 시 구문 에러를 유발하는 주요 원인이 됩니다.
- **해결책:** 기존 Biped 본의 이름은 유지하되, 추가적인 셋업(Control 등)에는 `Ctrl_L_Prop1`과 같이 명확하게 언더바를 사용해 주세요.

---

## 💡 결론: 3ds Max 리깅 네이밍의 정석

3ds Max 리깅 환경에서는 가장 많이 쓰이는 **Biped를 베이스**로 삼으시면 됩니다.

1. **기본 문법:** Pascal Case를 기반으로 하되, 단어 구분은 오류 방지를 위해 공백 대신 **언더바(`_`)**를 사용합니다.
2. **Biped 본:** 기존 Biped 시스템의 본 이름은 표준이므로 그대로 유지합니다.
3. **확장 노드:** 추가되는 컨트롤러나 보조 본은 Biped의 부위 명칭과 통일감을 주는 것이 좋습니다.

---

## 📌 자주 쓰이는 네이밍 리스트

팀 내에서 참고하실 수 있도록 실무에서 자주 활용되는 명칭들을 정리해 드릴게요.

### **Prefix (타입 리스트)**

- **`Ctrl_`**: 애니메이터가 실제로 키를 잡는 컨트롤러 요소
- **`Off_`**: 컨트롤러의 상위 Offset 그룹 (수정 및 관리용)
- **`Skin_`**: 메시(Mesh)에 스킨 노드로 할당되는 실제 본(Bone)들
- **`Pt_`**: Points, 주로 리깅 시스템 내에서 활용되는 보조 노드

### **Middle (방향 및 위치)**

- **`L` / `R`**: 왼쪽(Left) / 오른쪽(Right)
- **`C` / `M`**: 중앙(Center/Middle) - 보통은 생략 가능합니다.

### **Suffix (부위 명칭)**

부위 이름은 가급적 **Biped의 명칭과 통일**하는 것이 가장 좋습니다.

- **추천 예시:** `Ctrl_L_Calf` (O) / `Ctrl_L_Knee` (X)
- **이유:** 무릎 부위라도 Biped의 실제 본 이름이 `Bip001 L Calf`라면, 혼선을 줄이기 위해 `Calf` 기반으로 이름을 맞추는 것이 효율적입니다.
- **주요 명칭:** `Thigh`, `Calf`, `Foot`, `Spine`, `Neck`, `Clavicle` 등
@@

---

# bone-option-pitfalls

> slug: bone-option-pitfalls

안녕하세요, **오타쿠 솔루션즈**입니다.

오늘은 리깅 입문자부터 실무자까지, 의외로 많은 분이 놓치고 있는 **3ds Max Bone 옵션의 함정**과 그로 인해 발생하는 **실제 사고 사례**를 공유하려 합니다.

### 😱 실제 사례: "애니메이션을 불러왔더니 캐릭터가 찌그러졌어요"

리깅 작업을 하다 보면 이런 황당한 경우를 겪게 됩니다.

1. **사례 A (엔진 불일치):** 맥스 뷰포트에서는 분명 Bone의 **Squash(스쿼시)** 효과가 찰지게 먹히고 있는데, 엔진(Unity/Unreal)에 올리니 캐릭터 쉐잎이 미동도 하지 않는 경우.
2. **사례 B (데이터 유령):** 애니메이션 데이터를 저장(Save/Load Animation)하고 다시 불러왔더니, 분명 건드린 적 없는 **Bone에 이상한 스케일(Scale) 값**이 생겨서 리깅이 뒤틀려버리는 경우.

---

### 🔍 왜 이런 일이 벌어질까요?

#### 1. 뷰포트의 '시각적 렌더링' vs '실제 데이터'의 차이

Bone 옵션의 스트레치와 스쿼시는 **3ds Max 뷰포트 내에서만** 그럴싸하게 보여주는 '가짜 변형'입니다.

- **실제 데이터:** Transform(Position, Rotation, Scale) 값은 전혀 변하지 않습니다.
- **결과:** 엔진은 '데이터'를 기반으로 작동하기 때문에, 데이터가 변하지 않은 본은 엔진에서 당연히 움직이지 않습니다. 맥스 화면만 보고 "오, 잘 되네!" 했다가 엔진에서 뒤통수를 맞는 격이죠.

#### 2. 애니메이션 로드(Load) 시 발생하는 데이터 혼선

더 큰 문제는 애니메이션 데이터를 재사용할 때 발생합니다. Bone 옵션이 켜진 상태에서 애니메이션을 저장하고 불러오면, 맥스가 이 '시각적 변형'을 '데이터'로 억지로 환산하려다 오류를 일으킵니다.

- **결과:** 본에 없던 **Scale 값이 1.1, 0.9** 식으로 멋대로 들어가면서 리깅 교체나 애니메이션 재사용 시 작업 전체를 꼬이게 만듭니다.

---

### 💡 전문 리거의 해결책: "정직한 리깅"

전문적인 게임 리거라면 편법 옵션 대신 **정공법**을 써야 합니다.

- **LookAt Constraint & Script Controller:** 본의 길이를 조절하고 싶다면, 두 지점 사이의 거리를 계산해 **실제 Scale 값**이 변하도록 리깅 구조를 직접 설계하세요.
- **데이터의 투명성:** 그래야만 엔진에서도 똑같이 나오고, 애니메이션 데이터를 주고받을 때도 수치가 틀어지지 않습니다.

---

### 🚀 [Tool] 사고 방지용: Bone 옵션 일괄 Off 스크립트

이미 작업된 본들이 불안하시다면, 아래 스크립트로 모든 본의 '눈속임 옵션'을 일괄 제거하세요. 리깅의 정석으로 돌아가는 첫걸음입니다.

```maxscript
-- Bone의 가짜 스트레치/스쿼시 옵션을 완전히 끄고 데이터 혼선을 막습니다.
for b in objects where classof b == BoneGeometry do (
    b.realignSelf = false
    b.freezeLength = false -- 길이 고정 해제 (데이터 계산 방해 방지)
    b.stretch = #none      -- 가짜 스트레치 해제
    b.sidefin = false      -- (선택사항) 불필요한 핀 제거
    print (b.name + " : Clean up completed.")
)
```

---

### 📝 요약하며

> **"리깅은 눈이 아니라 '데이터'로 하는 것입니다."**
> 편리해 보이는 Bone 옵션, 게임 프로덕션에서는 오히려 독이 될 수 있습니다. 지금 바로 여러분의 본 세팅을 점검해 보세요!
@@

---

# 3ds Max → Unity FBX 익스포트 완전 가이드

> slug: max-to-unity-fbx-export

3ds Max에서 리깅·스킨한 캐릭터를 **Unity로 정상 반입**하기 위한 표준 절차입니다.
"왜 이렇게 하는가"를 이해하면 씬이 달라져도 스스로 대응할 수 있습니다.

---

## 0. 성공 기준 — 딱 이 화면이 나오면 끝

Unity에 FBX를 끌어다 놓고 **Root**(최상위 오브젝트)를 선택했을 때, Inspector의 Transform이 아래와 같아야 합니다.

| 항목 | 값 |
|------|-----|
| **Position** | 0, 0, 0 |
| **Rotation** | 0, 0, 0 |
| **Scale** | 1, 1, 1 |

![목표 - Unity 씬 전체](max-to-unity-fbx-export/image.png)

![목표 - Root Transform](max-to-unity-fbx-export/image_1.png)

**왜 이 값이 중요한가?**
Root가 `0 / 0 / 1`로 깨끗해야 Prefab화, 애니메이션 리타게팅, 물리·콜라이더 계산이 모두 예측 가능해집니다.
Scale이 `0.01`이나 Rotation이 `-90`으로 들어가면, 그 오차가 하위 본·메시·애니메이션 전체에 누적되어 나중에 원인 추적이 매우 어려워집니다. **문제는 반입 시점에 잡는 것이 가장 쌉니다.**

---

## 1. 왜 좌표와 단위가 어긋날까 (필수 배경 지식)

3ds Max와 Unity는 **좌표계와 기본 단위가 서로 다릅니다.** FBX 파일이 그 사이를 번역하는 다리 역할을 하는데, export 옵션이 틀리면 번역이 어긋나 위 값이 깨집니다.

| 구분 | 3ds Max | Unity |
|------|---------|-------|
| **Up 축 (위쪽)** | **Z-up** (Z가 하늘) | **Y-up** (Y가 하늘) |
| **좌표계 손잡이** | Right-handed | Left-handed |
| **내부 길이 단위** | 씬 단위 자유 (**cm 권장**) | **1 unit = 1 meter 고정** |

핵심은 두 가지입니다.

- **축**: Max의 Z-up을 Unity의 Y-up으로 돌려줘야 캐릭터가 눕지 않습니다.
- **단위**: Unity는 "1 = 1미터"로 못 박혀 있습니다. Max를 cm로 작업하면 1cm = 0.01m이므로, FBX가 이 100배 차이를 올바르게 흡수해줘야 Scale이 `1`로 떨어집니다. 흡수가 안 되면 `0.01`이 그대로 남습니다.

> 이 가이드의 모든 단계는 결국 **"축을 Y-up으로, 단위를 cm 기준으로"** 맞추기 위한 것입니다.

---

## 2. STEP 1 — 씬 단위 확인 (cm 기준)

먼저 Max 씬이 어떤 단위인지 확인합니다. `Customize > Units Setup` 메뉴로 들어갑니다.

![Units Setup 메뉴 위치](max-to-unity-fbx-export/image_2.png)

`Display Unit Scale`을 **Metric → Centimeters**로 둡니다.

![Units Setup - Centimeters](max-to-unity-fbx-export/image_3.png)

**왜 cm인가?**
BipedPlus의 내부 계산(높이·스케일 등)이 **cm를 기준(SSOT)**으로 삼습니다. 또한 Max의 표준 export 관례가 cm이기 때문에, cm로 맞춰두면 뒤의 FBX 단위 변환이 가장 깔끔하게 맞아떨어집니다.

> 회사 파이프라인이 m(meter)로 고정돼 있어도, **최소한 리깅·export 단계에서는 cm 권장**입니다. (m 씬 지원은 툴 개선 예정 항목)

---

## 3. STEP 2 — 축 정렬 (Z-up → Y-up)

Max는 Z가 위, Unity는 Y가 위입니다. export 전에 **Root를 기준으로 방향을 Unity 관례(Y가 위, Z가 앞)에 맞춰 정렬**합니다.

![Max 리그 계층과 축](max-to-unity-fbx-export/image_4.png)

> 3ds Max 기준 **Y를 위쪽, 앞(정면)을 Z축**으로 잡으면 Unity와 방향이 맞습니다.

정렬 방법: Root를 선택하고 **World 기준으로 X축 +90° 회전**합니다. (Rotate Transform Type-In → `Absolute:World` X = 90)

![World X +90도 회전](max-to-unity-fbx-export/image_5.png)

**왜 X축 90°인가?**
Z-up 공간을 Y-up 공간으로 눕히려면 위쪽 벡터를 Z에서 Y로 90° 굴려야 합니다. 이 회전이 곧 두 엔진의 "위쪽" 정의 차이를 메워주는 값입니다.

---

## 4. STEP 3 — Export 대상만 선택 (스킨본 + 메시)

export할 때 **스킨 본 트리 + 메시(지오메트리)만** 선택합니다. 컨트롤러·헬퍼·리그 그룹(`Ctrl_World`, `Grp_Rig`, `Drv_Root` 등)은 **넣지 않습니다.**

![스킨본 + 메시 트리만 선택](max-to-unity-fbx-export/image_6.png)

**왜 리그 전체를 넣으면 안 되는가?**
Unity가 실제로 필요로 하는 것은 **스킨드 메시 + 그것을 움직이는 스켈레톤**뿐입니다. 리그 컨트롤러/헬퍼는 게임엔진에서 쓸모없을 뿐 아니라,

- 불필요한 본 계층이 늘어 임포트가 무거워지고,
- 스케일·오프셋이 걸린 컨트롤 노드가 섞여 들어가면서 **Scale 0.01 같은 오염**을 유발합니다.

> 원칙: **"게임에 필요한 것만" 내보낸다.**

---

## 5. STEP 4 — FBX Export 옵션

### (1) Include — 애니메이션 & 디포메이션

- **Animation** 체크
- **Deformations → Skins, Morphs** 체크 (스킨 웨이트와 모프가 함께 나가야 함)

![FBX Include 옵션](max-to-unity-fbx-export/image_7.png)

### (2) Advanced Options — 단위 & 축

가장 중요한 부분입니다. 앞서 설명한 단위·축 변환이 여기서 최종 결정됩니다.

| 옵션 | 값 | 의미 |
|------|-----|------|
| **Units → Automatic** | 체크 | 씬 단위를 자동 감지해 변환 |
| **Scene units converted to** | **Centimeters** | 씬이 cm이므로 cm로 내보냄 |
| **Scale Factor** | **1.0** | 추가 배율 없음 (변환은 단위가 담당) |
| **Axis Conversion → Up Axis** | **Y-up** | Unity의 위쪽 축에 맞춤 |

![FBX 단위 · 축 옵션](max-to-unity-fbx-export/image_8.png)

**왜 이 조합인가?**
`Scale Factor 1.0` + `cm` + `Y-up`이면, Unity가 임포트 시 cm→m(÷100)와 축 변환을 알아서 흡수해 **Root Scale이 정확히 1.0**로 떨어집니다. 여기서 Scale Factor를 임의로 만지면 100배/0.01배 오차가 다시 생깁니다.

> Unity 쪽 up 축은 Y이므로 **반드시 Y-up**으로 내보냅니다.

---

## 6. STEP 5 — Unity 반입 검증

FBX를 Unity로 끌어와 Root를 선택하고, **[0. 성공 기준]**과 동일한지 확인합니다.

- Position 0, 0, 0
- Rotation 0, 0, 0
- Scale 1, 1, 1

여기까지 맞으면 정상 반입 완료입니다.

---

## 7. 흔한 실수 & 트러블슈팅

### 실수 1 — Root Scale이 `0.01`로 들어온다

![잘못된 예 - Scale 0.01](max-to-unity-fbx-export/image_9.png)

> **기본값이 아닌 Root 본을 넣으면 안 됩니다.**

**원인**: 트랜스폼이 초기화(기본값)되지 않은 Root/컨트롤 노드를 export에 포함시킨 경우입니다. 그 노드에 걸린 `0.01` 스케일(또는 cm↔m 미변환분)이 그대로 Unity Root에 baked-in 됩니다.

**해결**:
- Export 대상에서 **컨트롤러/헬퍼 Root를 제외**하고, 트랜스폼이 깨끗한 스킨 본 트리 + 메시만 내보냅니다. (STEP 3 참고)
- FBX 옵션의 `Scale Factor`가 `1.0`, `Units = Centimeters`인지 재확인합니다.

---

### Q&A — Scale에 `0.9999999`가 들어와요. 문제인가요?

![Scale 0.9999999](max-to-unity-fbx-export/image_10.png)

**결론: 정상입니다.** 3D 그래픽은 값을 **부동소수점(floating point)**으로 저장하기 때문에, 여러 번의 행렬 변환(회전·단위 환산 등)을 거치면 `1.0`이 `0.9999999`처럼 미세하게 떨어질 수 있습니다. 이는 오차라기보다 **연산의 자연스러운 반올림 결과**이며, 실사용에 영향이 없습니다.

**그래도 값을 깔끔하게 `1.0`으로 만들고 싶다면**: 해당 노드의 트랜스폼을 **PRS 채널로 리셋**한 뒤, Position은 **Position Constraint**, Rotation은 **Orientation Constraint**로 교체합니다. (Transform Script 대신 순수 PRS로 정리)

![Transform Script → PRS + Constraint](max-to-unity-fbx-export/image_11.png)

이렇게 하면 누적 오차 없이 값이 정리됩니다.

![정리 후 - Scale 1.0](max-to-unity-fbx-export/image_12.png)

---

## 8. 최종 체크리스트

내보내기 전에 이 5줄만 확인하면 됩니다.

- [ ] **단위**: 씬이 Centimeters (`Customize > Units Setup`)
- [ ] **축**: Root를 World X **+90°** 회전 (Y-up 정렬)
- [ ] **선택**: 스킨 본 트리 + 메시만 (컨트롤러·헬퍼 제외)
- [ ] **FBX 옵션**: Units `Automatic / cm`, Scale Factor `1.0`, Up Axis `Y-up`, Animation·Skins·Morphs 체크
- [ ] **Unity 검증**: Root Transform = `0/0/0 · 0/0/0 · 1/1/1`

> `0.9999999` 스케일은 정상 오차이며, 신경 쓰일 경우에만 PRS 리셋 + Constraint로 정리합니다.