UnrealEngine4でMMDの表情アニメーションを読み込む
目的
UnrealEngine4(以下UE4)に、MMDモデルの表情モーションを読み込ませます。
方針
MMDの表情モーションデータ(.VMD)をcsv形式に変換し、UE4で扱えるDataTable型としてインポートします。Blueprintの機能を利用して、インポートしたデータを、アニメーションシーケンスへ書き込みます。
前置き
MMDモデルとそのボーンアニメーションはFBXファイルに変換して読み込む方法を取っています。
①アニメーションシーケンスへのキー登録について
表情の情報はモーフターゲットと呼ばれる形で格納され、その情報はスケルタルメッシュの中にあります。元のデータが日本語の為、モーフターゲット名が???(※1)になっていますが、元は「まばたき」や「にっこり」などの日本語です。PmxEditorの内容と一致しています。
アニメーションシーケンスのエディット画面から、モーフターゲット名と同じ名前でカーブを追加し、キーを登録することでアニメーションが設定されます。つまり、ここへキーを自動登録することが目的になります。
(※1)
大体、ASCIIコード以外の文字1つにつき、?が3つ並ぶみたいです。csvに変換するときにこの法則を利用していますが、100%ではないので手作業で直しています。
②表情モーションデータ(.VMD)の入力方法について
表情モーションのデータはFBXファイルからインポートできていないようです。構造体の中を探しましたがそれらしいものがありませんでした(見つけられていないだけかもしれません)。その為、外部から読み込む方法を取りました。しかしUE4では、基本的にデータを扱いたいときはコンテンツ内のアセットから読むしかなく、アセットとしてインポートできる型式も限られています。そこで、表情モーションデータ(.VMD)をcsvに変換し(※2)、UE4のDataTableの型としてインポートすることで、アセットとしてアクセスさせるようにしました。
インポートできるようにするため、自前でDataTableの1行となる型を宣言します。FTableRowBase型を継承します。ここで、変数名はcsvのタイトル行と合わせる必要があります。必要な情報は、「モーフターゲット名、キー位置(フレーム番号)、キー値」です。
USTRUCT() struct BLUEPRINTOFFICE_API FMorphAnimationTable : public FTableRowBase { GENERATED_USTRUCT_BODY() /** Full Path of Blueprint */ UPROPERTY(EditAnywhere, Category = Pawn) FString Morph_Name; /** Category of GamePlay Object */ UPROPERTY(EditAnywhere, Category = Pawn) float frame; /** Scriptable Use Code */ UPROPERTY(EditAnywhere, Category = Pawn) float Value; };
これで、DataTableのインポート時に自分で作った型が表示されます。今回は、FMorphAnimationTableです。
(※2)
MMDのモデルとモーションのフォーマットが公開されているのでそれを元にツールを作って変換しています。
③Blueprintでの処理について
①の内容を出力、②の内容を入力として、モーション自動登録用のBlueprintを作成します。
必要な引数は、「対象のモデル(スケルタルメッシュ)、対象のアニメーションシーケンス、読み込んだDataTable、DataTableのデータ数」です。「DataTableのデータ数」の引数がかっこ悪いです。DataTableの行数を読む方法が見つかりませんでした。
関数内で行っていることは単純で、DataTableを一行ずつ読み、モーフターゲット名と一致したカーブ名に、キーを登録しているだけです。
bool UMyBlueprintFunctionLibrary::VMDRead(USkeletalMesh* mesh, UAnimSequence* sequence, UDataTable* curveTable, INT32 data_num) { if (mesh == nullptr || sequence == nullptr || curveTable == nullptr) return false; USkeleton* Skeleton = sequence->GetSkeleton(); USkeleton::AnimCurveUID CurveUid; FFloatCurve* curve; FSmartNameMapping* NameMapping = Skeleton->SmartNames.GetContainer(USkeleton::AnimCurveMappingName); FName morphName; FMorphAnimationTable* dataRow; FString ContextString; //Clear Curves sequence->RawCurveData.Empty(); //Add Morph Curves for (INT32 i = 0; i < mesh->MorphTargets.Num(); i++){ if (Skeleton->AddSmartnameAndModify(USkeleton::AnimCurveMappingName, mesh->MorphTargets[i]->GetFName(), CurveUid)) { sequence->Modify(true); sequence->RawCurveData.AddCurveData(CurveUid); sequence->RawCurveData.GetCurveData(CurveUid)->LastObservedName = mesh->MorphTargets[i]->GetFName(); } else if (NameMapping->AddOrFindName(mesh->MorphTargets[i]->GetFName(), CurveUid)) { sequence->Modify(true); sequence->RawCurveData.AddCurveData(CurveUid); sequence->RawCurveData.GetCurveData(CurveUid)->LastObservedName = mesh->MorphTargets[i]->GetFName(); } } //AddKeys for (INT32 i = 0; i < data_num; i++){ dataRow = curveTable->FindRow<FMorphAnimationTable>(*FString::Printf(TEXT("%d"), i), ContextString); morphName = FName(*dataRow->Morph_Name); NameMapping->AddOrFindName(morphName, CurveUid); curve = static_cast<FFloatCurve*>(sequence->RawCurveData.GetCurveData(CurveUid, FRawCurveTracks::FloatType)); curve->FloatCurve.AddKey(dataRow->frame / 30.0, dataRow->Value); //UE_LOG(LogTemp, Warning, TEXT("%s, %f, %f"), *morphName.ToString(), dataRow->frame, dataRow->Value); } return true; }
作成したBlueprintを、Level Blueprintに記述し、実行させます。
実行に成功すれば、アニメーションシーケンスにモーション情報が書き込まれます。
書き込んで保存してしまえば、Blueprintがなくても移行して別プロジェクトで使うことができます。
このコードはまともなエラー処理がないので、引数を間違えたり、2回以上実行したりするとUE4ごと落ちます。
できました。カーブタイプをモーフカーブにするようチェックをいれます。
動画テストです↓
④使用させて頂いたモデル・参考にさせて頂いた記事など
MMDモデル・モーション
::Lat式ミクVer.2.31 for MikuMikuDance:: / Lat さんのイラスト - ニコニコ静画 (イラスト)
【MMD-DMC3】galaxias! ‐ ニコニコ動画:GINZA
MMDデータの読み込みについて
Happy my life | UE4でミクさんに可愛く踊ってもらう方法
UE4でMMDのモーションを使ってみる - ぼっちプログラマのメモ
UE4 モーフターゲットを使って表情を変えてみる - Let's Enjoy Unreal Engine
UnrealEngine4 について
Using excel to store gameplay data - DataTables - Epic Wiki
Unreal Engine | Unreal Engine API Reference
Unreal Engine | データ駆動型のゲームプレイエレメント
Unreal Engine | アニメーション カーブ
Unreal Engine | FBX モーフターゲット パイプライン
Unreal Engine | C++ とブループリント
Unreal Engine | プログラミング案内