# 3ds Max → Unity FBX エクスポート完全ガイド

3ds Maxでリグ・スキニングしたキャラクターを**Unityへ正しくインポート**するための標準手順です。
「なぜこうするのか」を理解すれば、シーンが変わっても自分で対応できます。

---

## 0. 成功基準 — この画面が出れば完了

FBXをUnityにドラッグ＆ドロップし、**Root**（最上位オブジェクト）を選択したとき、InspectorのTransformが以下の値になっている必要があります。

| 項目 | 値 |
|------|-----|
| **Position** | 0, 0, 0 |
| **Rotation** | 0, 0, 0 |
| **Scale** | 1, 1, 1 |

![目標 - Unityシーン全体](image.png)

![目標 - Root Transform](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がSky） | **Y-up**（YがSky） |
| **座標系の手** | 右手座標系 | 左手座標系 |
| **内部長さ単位** | シーン単位自由（**cm推奨**） | **1 unit = 1 meter 固定** |

重要なポイントは2つです。

- **軸**: MaxのZ-upをUnityのY-upに変換しないとキャラクターが横に倒れます。
- **単位**: Unityは「1 = 1メートル」が絶対固定です。Maxをcmで作業すると1cm = 0.01mなので、FBXがその100倍の差を正しく吸収しないとScaleが`0.01`のまま残ります。

> このガイドのすべてのステップは、結局**「軸をY-upに、単位をcm基準に」**合わせるためのものです。

---

## 2. STEP 1 — シーン単位の確認（cm基準）

まずMaxシーンの単位を確認します。`Customize > Units Setup`メニューに入ります。

![Units Setupメニューの場所](image_2.png)

`Display Unit Scale`を**Metric → Centimeters**に設定します。

![Units Setup - Centimeters](image_3.png)

**なぜcmか?**
BipedPlusの内部計算（高さ・スケールなど）が**cmを基準（SSOT）**としています。また、Maxの標準exportの慣例がcmなので、cmに合わせておくと後のFBX単位変換が最もきれいに一致します。

> スタジオのパイプラインがm（メートル）固定でも、**少なくともリグ・exportの段階ではcm推奨**です。（mシーン対応はツール改善予定）

---

## 3. STEP 2 — 軸の整列（Z-up → Y-up）

MaxはZ-up、UnityはY-upです。export前に**Rootを基準にUnityの慣例（Y上、Z前）に合わせて方向を整列**します。

![Maxリグ階層と軸](image_4.png)

> 3ds Max基準で**Yを上、前方（正面）をZ軸**にするとUnityの方向に合います。

整列方法：Rootを選択し、**ワールド基準でX軸+90°回転**します。（Rotate Transform Type-In → `Absolute:World` X = 90）

![World X +90°回転](image_5.png)

**なぜX軸90°か?**
Z-up空間をY-up空間に変換するには上方向ベクトルをZからYへ90°回転させる必要があります。この回転が2つのエンジンの「上方向」定義の差を埋める値です。

---

## 4. STEP 3 — Export対象の選択（スキンボーン + メッシュのみ）

exportする際は**スキンボーンツリー + メッシュ（ジオメトリ）のみ**を選択します。コントローラー・ヘルパー・リググループ（`Ctrl_World`、`Grp_Rig`、`Drv_Root`など）は**含めません。**

![スキンボーン + メッシュツリーのみ選択](image_6.png)

**なぜリグ全体を含めてはいけないか?**
Unityが実際に必要とするのは**スキンドメッシュ + それを動かすスケルトン**だけです。リグコントローラー/ヘルパーはゲームエンジンでは不要なだけでなく、

- 不要なボーン階層が増えてインポートが重くなり、
- スケール・オフセットがかかったコントロールノードが混入することで**Scale 0.01のような汚染**を引き起こします。

> 原則：**「ゲームに必要なものだけ」エクスポートする。**

---

## 5. STEP 4 — FBX Exportオプション

### (1) Include — アニメーション＆デフォーメーション

- **Animation** チェック
- **Deformations → Skins, Morphs** チェック（スキンウェイトとモーフが一緒に出力される必要あり）

![FBX Includeオプション](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のUp軸に合わせる |

![FBX単位・軸オプション](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](image_9.png)

> **デフォルト値でないRootボーンを含めてはいけません。**

**原因**: トランスフォームがリセット（デフォルト値）されていないRoot/コントロールノードをexportに含めた場合です。そのノードにかかっている`0.01`スケール（またはcm↔m未変換分）がそのままUnity Rootにbake-inされます。

**解決方法**:
- Exportの対象から**コントローラー/ヘルパーのRootを除外**し、トランスフォームがクリーンなスキンボーンツリー + メッシュのみエクスポートします。（STEP 3参照）
- FBXオプションの`Scale Factor`が`1.0`、`Units = Centimeters`かどうか再確認します。

---

### Q&A — Scaleに`0.9999999`が入ってきます。問題ですか?

![Scale 0.9999999](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](image_11.png)

こうすることで累積誤差なく値が整理されます。

![整理後 - Scale 1.0](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で整理します。