Slide 1

Slide 1 text

UnityのHumanoidと共存する キャラクタジョイント制御と 制作ワークフロー QualiArts 塩塚勇気

Slide 2

Slide 2 text

Contents • 自己紹介 • モバイルゲームに必要な キャラクタジョイント制御要素の整理 • ランタイムの基本骨補正 • 補助骨の仕様とワークフロー • 揺れ骨と高速化/汎用化テクニック • まとめ

Slide 3

Slide 3 text

1 自己紹介

Slide 4

Slide 4 text

塩塚 勇気 CyberAgent ゲーム・エンタメ事業部(SGE) 株式会社QualiArtsにて 「学園アイドルマスター」「IDOLY PRIDE」など モバイルゲーム開発に携わる。 テクニカルアーティストとして、 主にキャラクタアニメーション制御、 物理シミュレーション、パイプライン整備を担当。

Slide 5

Slide 5 text

ゲーム・エンターテイメント事業部(SGE) 子会社制をとっており、 ゲーム・エンターテイメント事業に 携わる10社の子会社が 所属しています。 ゲーム・エンターテイメント事業部(SGE)

Slide 6

Slide 6 text

モバイルゲームに必要な キャラクタジョイント制御要素 の整理 2

Slide 7

Slide 7 text

Muscle └Humanoidを制御する、 正規化されたパラメータ UnityHumanoidの紹介 Humanoid └人形キャラの標準リグ

Slide 8

Slide 8 text

UnityHumanoidの紹介 捻り補正 └手首などに捻り回転が、 肘(親階層)に分割される └階層構造にジョイントとして生成されない フルボディIK └手足のIK、重心操作

Slide 9

Slide 9 text

キャラ制御に求められる要件の整理 カットシーン └UnityのTimelineをベースとしたシステムとの連携が必要。 └時系列的な厳密性に加え、エディタ環境との調和が求められる。 スクリプト操作 └インゲームやアウトゲームなど、遊びやユーザー操作との連携が必要。 └ゲーム性により要件は異なるが、ゲームエンジニア視点での扱い易さ方法が求められる。 ※上記に対応したキャラ入れ替え、衣装入れ替えが必要な場合がある。

Slide 10

Slide 10 text

キャラ制御に求められる要件の整理 アニメーションの再生 └Timelineとの親和性が高い └他のシステムに干渉しない再生タイミングで完結 基本骨補正 └キャラ/衣装入れ替えへの対応 └IKなど、Humanoidシステムと競合しないランタイム操作 追加ジョイントの制御方法 └Humanoidと連携し、計算コストを抑えた 小道具骨/補助骨/揺れ骨 の制御

Slide 11

Slide 11 text

キャラ制御に求められる要件の整理 アニメーションの再生 └Timelineとの親和性が高い └他のシステムに干渉しない再生タイミングで完結 基本骨補正 └キャラ/衣装入れ替えへの対応 └IKなど、Humanoidシステムと競合しないランタイム操作 追加ジョイントの制御方法 └Humanoidと連携し、計算コストを抑えた 小道具骨/補助骨/揺れ骨 の制御

Slide 12

Slide 12 text

アニメーションの再生 Update ProcessAnimation LateUpdate Animation C# Jobs 基本骨補正 小道具骨 補助骨 揺れ骨 ゲームロジック... カメラ操作... 他のシステムに干渉しない再生タイミングで完結

Slide 13

Slide 13 text

Playable API PlayableGraph と呼ばれるツリー構造で、アニメーションやスクリプト等を、 ミックス/ブレンド/変更を行い、1つの出力として再生する仕組み。 アニメーションのブレンド後に任意の処理を追加するなどが可能。 AnimatorControllerやTimelineはこの仕組みで作成されている。 出力 任意の処理 ミックス タイムライン...

Slide 14

Slide 14 text

ランタイムの基本骨補正 3

Slide 15

Slide 15 text

衣装ボリュームに対応するIK 衣装ボリュームによる手の埋まり キャラ/衣装入れ替えがある場合、 汎用モーションでは手の浮き/埋まりが発生する。 埋まり発生 埋まりなし

Slide 16

Slide 16 text

衣装ボリュームに対応するIK IK補正コライダ 衣装の概形に沿うコライダを作成し、 手が入らないようにするポーズ補正処理。 FKで流したアニメーションをIKで補正するため、 カクつきが発生した。 埋まりなし 埋まりなし

Slide 17

Slide 17 text

衣装ボリュームに対応するIK 減衰領域を使用したカクつきへの対応 侵入不可領域と減衰領域を作成。 減衰領域をローパスフィルタとして実装、 カクつきの抑制を行った。 減衰領域 不可侵領域

Slide 18

Slide 18 text

Muscleを使用した加算モーション 発話時の頷き加算 簡易な会話シーンにおいて、 発話時に首と頭が頷くように動いてほしい。

Slide 19

Slide 19 text

Muscleを使用した加算モーション シンプルな実装の問題点 揺れ骨計算が終わった後に加算しているため、 頷きによる揺れが反映されず固く見えてしまう。 Update ProcessAnimation LateUpdate 音声の再生 FFTで発話状況を取得 揺れ骨計算 発話時なら 首と頭のローカル回転に加算

Slide 20

Slide 20 text

Muscleを使用した加算モーション 改善した実装 ProcessAnimation内で、Muscle値に対して加算を行う。 加算を行った後に揺れ骨計算を行い、揺れに反映する。 (±40度のローカル回転を、±1のMuscle範囲とするのが標準設定) Update ProcessAnimation 音声の再生 FFTで発話状況を取得 頷きウェイトから首と頭 のMuscle値に加算 揺れ骨計算

Slide 21

Slide 21 text

Muscleを使用した加算実装 public void ExecuteNodAdditive(AnimationStream stream) { AnimationHumanStream humanStream = stream.AsHuman(); # アニメーションから指定されたMuscle値を取得 float currentMuscleValue = humanStream.GetMuscle(muscleHandle); # 加算したい回転値を、Muscle値に変換。(±40度のローカル回転を、±1のMuscle値とする) float additiveDegree = additiveDegree.GetFloat(stream); float additiveMuscleValue = additiveDegree / 40.0f; # 最終的なMuscleを設定 humanStream.SetMuscle(muscleHandle, currentMuscleValue + additiveMuscleValue); }

Slide 22

Slide 22 text

補助骨の仕様とワークフロー 4

Slide 23

Slide 23 text

ゲームエンジンでの補助骨 衣装入れ替えを想定し、ランタイムで駆動する補助骨を実装。 衣装追加時にも既存アニメーション再書き出しが不要、 モーションデータの容量削減に貢献。 基本骨 補助骨 連動

Slide 24

Slide 24 text

簡易な補助骨例 人体形状の保持 揺れ骨のサポート

Slide 25

Slide 25 text

簡易な補助骨例 人体形状の保持 揺れ骨のサポート

Slide 26

Slide 26 text

揺れ骨のサポート補助骨 基本骨補正の後、揺れ骨の前に行う必要がある Animation C# Job 基本骨補正 小道具骨 補助骨 揺れ骨 太腿の回転取得 ステレオ投影法で 軸ごとの曲げ分解 前後曲げ連動計算 前後スカートの 回転設定 左右曲げ連動計算 左右スカートの 回転設定

Slide 27

Slide 27 text

Humanoidと人体補助骨の両立 肘曲げ補助骨 肘の形状を保つため、肘への捻り分解はオフにしたい。 前腕ひねり補助骨 前腕部の捻り補助骨を任意の数だけ使用したい。

Slide 28

Slide 28 text

Humanoidと人体補助骨の両立 肘曲げ補助骨 肘の形状を保つため、肘への捻り分解はオフにしたい。 対応 LowerArmTwistを0にすることで、 肘への影響を0にする。 肘の曲げ回転値をもとに、補助骨を駆動。

Slide 29

Slide 29 text

Humanoidと人体補助骨の両立 前腕ひねり補助骨 前腕部の捻り補助骨を任意の数だけ使用したい。 (手首のローカル回転を参照して捻り補助骨を制御をしたいが、 Muscle制御につき正確なローカル回転値が得られない。) 対応 Muscle値を回転値に読み替え、連動計算を行う。 ±90度のローカル回転を、±1のMuscle範囲とするのが標準設定だが、 ±66度で変換するのがよい結果を得られた。 LowerArmTwistの設定値調整により、最適な読み替え係数が変化。 手首捻りの Muscle値を取得 捻り連動計算 前腕捻り補助骨に 回転値を設定 Muscle値から 回転値に変換

Slide 30

Slide 30 text

Muscleを使用した補助骨実装 public void ExecuteHandTwist(AnimationStream stream) { AnimationHumanStream humanStream = stream.AsHuman(); # アニメーションから指定されたMuscle値を取得 float muscleValue = humanStream.GetMuscle(muscleHandle); # 駆動する回転値を、Muscle値から算出。(±66度のローカル回転を、±1のMuscle値とする) float handTwistDegree = muscleValue * 66; Quaternion driverQuat= Quaternion.Euler(handTwistDegree * driverCoefficient, 0, 0); # 最終的なMuscleを設定 driverHandle.SetLocalRotation(stream, driverQuat); }

Slide 31

Slide 31 text

ワークフロー Mayaではローカル回転をベースに駆動計算を行い、 Unityではローカル回転モードとMuscleモードで駆動計算を行う。 基本骨 補助骨 連動 基本骨 補助骨 連動 設定 ファイル

Slide 32

Slide 32 text

ツール使用で効率化 セットアップ、バリデート、 Unityへの書き出しなど、量産時はツール効率化。 ワークフロー 独自ノードで駆動 汎用ノードと固有ノードがあり、 部位ごとのテンプレ化が容易。 検証時は手動でノード接続可能。

Slide 33

Slide 33 text

ワークフロー 構成によらず一様にセットアップ 階下の補助骨コンポーネントを収集。 着せ替えや追加パーツによらずセットアップ可能。 コンポーネントを付与し駆動 設定ファイルを介したセットアップ、 通常/Muscleモード対応、 座標系の差異の吸収を自動で行う。 Characterルート 髪 体 小道具

Slide 34

Slide 34 text

揺れ骨と 高速化/汎用化テクニック 5

Slide 35

Slide 35 text

C# Job System マルチスレッドで処理実行する仕組み Animation C# Jobs AnimationStreamにアクセスして任意処理を実行するためのJob System機能 Burstコンパイラ High Performance C#で高速なコードを生成するコンパイラ Unity標準の高速化

Slide 36

Slide 36 text

Job統一による高速化と柔軟性 揺れ骨 補助骨 基本骨 補正 切り替え オーバーヘッド オーバーヘッドの最小化 更新順番の完全制御 基本骨補正 + 小道具骨 + 補助骨 + 揺れ骨

Slide 37

Slide 37 text

座りモーションの課題 身長に応じたモーション補正 制作工数を考慮し、 汎用モーションベースのシステムで補正したい。 椅子形状に沿った衣装形状変化 挙動安定性と制作コストから、 コライダ以外の手動が望ましい。

Slide 38

Slide 38 text

座りモーションの課題 身長に応じたモーション補正 制作工数を考慮し、 汎用モーションベースのシステムで補正したい。 椅子形状に沿った衣装形状変化 挙動安定性と制作コストから、 コライダ以外の手動が望ましい。

Slide 39

Slide 39 text

座りモーションの汎用化 通常 重心操作と足のIK 重心計算方法は非公開だが、ジョイント位置の加重平均である程度再現可能。 Mayaでも簡易プレビュー可能なワークフローを実現。

Slide 40

Slide 40 text

座りモーションの経験的な対応法 計算コストを抑えつつ、 ・キャラ入れ替え ・衣装入れ替え ・椅子の高さ などのバリエーションに対応。 通常 足への引力

Slide 41

Slide 41 text

まとめ 6

Slide 42

Slide 42 text

まとめ 〇AnimationC#Jobsを使用することで、Unity標準のアニメーションシステムと親和性の高く、 ゲーム性に依らないキャラクタ制御システムを実現。 〇Muscle値を使用した加算アニメーションと補助骨計算を行うことで、Humanoidと共存する表現 力の高いジョイント制御手法を実現。 〇補助骨のMayaとUntiy間のワークフローと、揺れ骨の高速化と汎用化の1事例を紹介。 Humanoidは独特な仕様もありますが、非常に有用な機能であり、 うまく付き合っていくことでメリットを享受しながら、独自の表現を行うことが可能です。 この知見がモバイルゲームでHumanoidを扱う皆様のお役に立てれば幸いです。

Slide 43

Slide 43 text

ご清聴ありがとうございました。