BipedPlus
Ep.18 — Customizing 03: ネーミング & チームテンプレート
Markdownダウンロード 画像込みダウンロードスタジオのネーミングルールに変更した後、一度だけ作成してcommonテンプレートとして再利用する方法をまとめたドキュメントです。
1. なぜ必要か
BipedPlusのデフォルトネーミング(Skin_*、Ctrl_*、Bip001)がチームのルールと異なると、ワークフローが詰まる場合があります。
変更することはできますが、毎回Renameを繰り返さないようにテンプレートとして保存することが重要です。
2. 全体パイプライン

3. ネーミング変更の許容範囲と注意事項
| 区分 | 内容 |
|---|---|
| ✅ 変更可能 | Biped名、Skinボーン名(エンジンボーン名一致目的)、コントローラー接頭辞、レイヤー表示名 |
| ⚠️ 注意 | Hierarchy / Constraint / Spaceが壊れないよう一括ルールでの変更を推奨 |
| ❌ Fix Missing省略禁止 | Rename後にFix Missingを省くとMirror / Picker / Resetがずれる |
4. Fix Missing — Rename後もシステムが追従するように
名前が変わると、INFOに記録された以前の名前とずれてMissingが発生します。
| 概念 | 説明 |
|---|---|
| Seed | 名前が変わってもノードを識別するためのユニークなアドレス値 |
| Fix Missing | Seedを使って新しい名前のノードを再リンクする機能 |
手順:Rig Info → Load → Missing確認 → Fix Missing実行 → ミラー更新確認 → Ani Utilsで検証
5. レイヤー名のカスタマイズ
レイヤー設定 → Edit Name → 新プリセット(チーム/プロダクト名)→ 接頭/接尾追加 → Apply to Rename
Hierarchyの役割分類は維持し、表示名だけチームに合わせます。
6. common テンプレートとして保存
| ステップ | 内容 |
|---|---|
| 1 | モデリングシーン(またはNew File)を開く |
| 2 | Merge — common/BP_Human_Template.maxのすべてのノード |
| 3 | BipedPlus Scan — INFO / ミラーなどが維持されているか確認 |
| 4 | Figure / 比率などキャラクター別調整 |
| 5 | キャラクターフォルダに保存 → アニメーションチームに配布(Playerで作業) |
共有_リギング/
├── character_A/
├── character_B/
└── common/
└── BP_Human_Template.max ← ネーミング・レイヤー・INFOまで設定済みマスター
7. Pickerの例外
| INFO / Ani Utils(Fix Missing後) | Picker | |
|---|---|---|
| Rename後 | 復旧可能 | 名前ベースのためレイアウトが崩れる可能性あり |
推奨:ネーミング・テンプレートが確定した後、新しいネーミングでPickerを再構成してチームに配布。
Pickerファイルの場所はBipedPlus Settingオプションで確認。
8. チェックリスト
- [ ] チームのbone / Ctrl / Layerネーミングルールが文書化されている
- [ ] 一括変更のためのRenameスクリプト(またはチームスクリプト)を使用している
- [ ] Rename後:Fix Missing + Mirror / Resetを検証している
- [ ]
common/テンプレート.maxが共有フォルダに存在する - [ ] 新キャラクターはMerge → Scanの手順を使用している
- [ ] Pickerは最終ネーミング基準で再構成している
- [ ] アニメーションチームはPlayerで同じインストーラーを使用している
Example Rename Script (handle 2-pass)
Edit NODE_RENAME_MAP to match your team's rules. Run in Max Script Editor after Build.
# -*- coding: utf-8 -*-
"""BipedPlus naming example (handle 2-pass, short version)"""
import pymxs
rt = pymxs.runtime
NODE_RENAME_MAP = [
("Bip001", "Bip009"),
("Bip001 Pelvis", "Bip009 Pelvis"),
("Ctrl_Head", "CTL_Head"),
("Skin_Spine1", "Bip001_Spine1"),
("Skin_L_Hand", "Bip001_L_Hand"),
]
def rename_nodes_by_handle(rename_map=None):
mapping = rename_map if rename_map is not None else NODE_RENAME_MAP
if not mapping:
raise ValueError("NODE_RENAME_MAP is empty.")
# Phase 1 — collect handles
collected = []
for src, dst in mapping:
node = rt.getNodeByName(src)
if node is None:
print(f"[SKIP] {src}")
continue
collected.append((int(node.handle), src, dst))
if not collected:
raise ValueError("No rename targets found in scene.")
# Phase 2 — apply
for handle, src, dst in collected:
node = rt.maxOps.getNodeByHandle(handle)
if node is None:
raise RuntimeError(f"handle={handle} restore failed ({src} → {dst})")
node.name = dst
print(f"[OK] {src} → {dst}")
print(f"Done ({len(collected)} ok). Next: Rig Info → Fix Missing")
if __name__ == "__main__":
rename_nodes_by_handle()
After running: Rig Info → Fix Missing → verify Mirror / Reset.