Blenderのシェイプキーで顔のアニメーションを作成しUnityで使用してみる

今回はBlenderで作成したキャラクターにシェイプキーを使って顔のアニメーションを作成し、それをUnityで使ってみたいと思います。

以前にボーンを操作して顔のアニメーションを作成してUnityで使いましたが、

MakeHumanキャラをBlenderで顔のアニメを付けてUnityに取り込む
MakeHumanでキャラクターの作成とボーンの設定をしてMHX2ファイルで出力し、Blenderに取り込んで表情のアニメーションを付けたらFBXファイルで出力しUnityに取り込んで使用してみます。

今回はボーンを使ったアニメーションではなく直接メッシュの頂点の位置を動かして作るシェイプキーのアニメーションを使って顔のアニメーションを作成します。

シェイプキーで顔のアニメーションを作成する前にキャラクターにモディファイアを取り付けている場合はアーマチュアモディファイア以外のモディファイア(例えばミラーモディファイア)を適用させておいてください。

シェイプキーでアニメーションを作る前にモディファイアを適用する

モディファイアが残っているとFBXとしてファイル出力する時にシェイプキーのエクスポートがおかしくなるようです。

モディファイアが適用されていないとシェイプキーのエクスポートがうまく適用されない可能性がある

今回の記事では以下のようにBlenderで作成したシェイプキーを使ったアニメーションがUnityでも使えます。

上の例ではAnimatorControllerのレイヤーとアバターマスクを使って顔だけのアニメーションを再生させています。

スポンサーリンク

Blenderで顔のアニメーションを作成する

まずはBlenderのシェイプキーを使ってキャラクターの顔のメッシュを移動させてアニメーションを作成していきます。

まずはオブジェクトモードで顔を含むオブジェクトを選択し、オブジェクトデータプロパティのシェイプキーの右の+を押します。

Blenderでシェイプキーを追加する

するとシェイプキーにベースが追加されます。

このベースが元の形状になります。

続けてシェイプキーの右の+を押して新しく出来たキー1の名前を変えてBlink(瞬き)とします。

Nキーを押してサイドバーを表示し、ツールのミラーのXを有効にします。

BlenderのサイドバーのツールでミラーのXをオンにする

Blinkを選択した状態でTabキーを押して編集モードにし、目を閉じるように頂点を選択して移動させます。

瞼にあたる部分の頂点を選択し、目を閉じるように下に移動させます(ミラーのXを有効にしたので片方の頂点を移動すると反対側も同じように動きます)。

シェイプキー用に瞼を下に移動させていく

完全に目を閉じるように移動させます。

瞬き用に目を閉じるように頂点を動かす

シェイプキーを使う時は頂点の数は変更せず位置だけを変更するようにします。

ここまで出来たら瞬きのアニメーションを作成していきます。

Tabキーを押してオブジェクトモードに戻ります。

タイムラインの1フレーム目に移動します。

瞬き用のシェイプキーのフレーム1のキーフレーム作成

オブジェクトデータプロパティのシェイプキーのBlinkを選択し、値を0にし、その値の上でキーボードのIキーを押してキーフレームを打ちます。

目を開いた状態でキーフレームを打つ

次にタイムラインの5フレームに移動させ、オブジェクトデータプロパティのシェイプキーのBlinkを選択し、値を1にした状態でキーボードのIキーを押してキーフレームを打ちます。

5フレーム目で目を閉じるようにする

10フレーム目に移動し、シェイプキーのBlinkを選択し、値を0にした状態でIキーを押してキーフレームを打ちます。

これで1フレームから10フレームまでで瞬きをするアニメーションが出来ました。

10フレーム目で再び目を開くようにキーフレームを打つ

シェイプキーアニメーションがうまく出力されない!

これで瞬きのアニメーションが出来ましたが、このままシェイプキーのアニメーションだけを出力しようとしてもUnityで反映されなかったので、適当にボーンを動かして体のアニメーションも作成します。

タイムラインの1フレーム目に移動し、ポーズモードにしたら左手のIKを選択しIキーを押して位置/回転をキーフレームに打ちます。

1フレーム目は左手のIKの位置と回転をキーフレームに打つ

10フレーム目に移動し、左手のIKを選択し適当に移動させてIキーを押し、位置/回転をキーフレームに打ちます。

10フレーム目は左手のIKの位置を動かし位置と回転をキーフレームに打つ

通常のアニメーションとシェイプキーを組み合わせる場合はボーンで作成するアニメーションをちゃんと作ってください。

今回は顔のアニメーションしか使わないので胴体は適当に動かしました。

FBXファイル出力

Blenderのファイルメニューからエクスポート→FBXを選択します。

Blenderから瞬きのアニメーションFBXファイルの出力

オブジェクトタイプをアーマチュアとメッシュのみShiftキーを押しながら選択します。

スケールを適用ではすべてFBXにし、出力します。

瞬きアニメーションFBX出力設定

UnityでFBXファイルを取り込み設定をする

出力したらUnityのAssetsフォルダ内で右クリックからImport New Assetを選択し出力したFBXファイルを取り込みます。

取り込んだらファイルを選択し、インスペクタのModelタブでImport BlendShapesにチェックが入っているのを確認します(デフォルトで入っているはず)。

UnityのModelでImport BlendShapesにチェックが入っているのを確認する

次にRigタブを選択しAnimation TypeをHumanoidにしApplyボタンを押します。

瞬きアニメーションを持つキャラクターをHumanoid型にする

Animationタブを選択し、取り込んだアニメーションが正常に動作するか確認します。

また、瞬きアニメーションは繰り返し再生したいのでLoop Timeにチェックを入れApplyを押します。

Unityで瞬きアニメーションが正常にされるかどうか確認する

以下のように瞬きと手の動きがUnityでも再生されているのを確認します。

瞬きアニメーションの動き

ここで複数のいらないアニメーションが取り込まれてしまった場合はそのアニメーションを選択し、-を押してそのクリップを削除します。

Blenderで作成されてしまったいらないアニメーションを削除する

わたくしの場合はうまい具合にひとつのアニメーションだけが取り込まれたので削除はしませんでした。

顔のアニメーションだけを使う

今回使用するのは顔のアニメーションだけなのでアバターマスクとAnimatorControllerのレイヤーを使って顔のアニメーションだけを上書きする事にします。

Assetsフォルダ内で右クリックからAvatar Maskを選択し、名前をHeadAvatarMaskとし、インスペクタで頭だけを緑色にして有効にします。

顔だけのアニメーションを使う為アバターマスクを設定する

AnimatorControllerはBase LayerでIdle状態とWalk状態を作りアニメーションパラメータ―Speedの値によってアニメーションを切り替えているとします。

新たにレイヤーを作成し、名前をHeadとします。

AnimatorControllerに顔用のレイヤーを作成する

Headレイヤーを選択し、右の歯車を押したらWeightを1にし、Avatar Maskに先ほど作ったHeadAvatarMaskを設定し、Syncにチェックを入れてBase Layerと同期し同じ状態と遷移が表示されるようにします。

瞬き用の顔用レイヤーの設定をする

HeadレイヤーはHeadAvatarMaskを設定したので顔のアニメーションだけが再生されます。

さらにBlendingをOverrideにしているので、Source Layerに設定しているBase Layerのアニメーションを上書きします。

HeadのIdle状態を選択し、インスペクタに先ほど取り込んだキャラクターのアニメーションクリップを設定します。

HeadのWalkには何も設定しません。

これで機能が出来ました。

キャラクターが立ち止まっている時は瞬きをしますが、歩いている時は瞬きをしないようになりました。

スクリプトからシェイプキーの値を変更する

シェイプキーはUnityのSkinned Mesh RendererのBlendShapes項目に表示されるようになります。

瞬きアニメーションをするキャラクターのボディメッシュ

BlenderのシェイプキーがSkinnedMeshRendererに表示される

わたくしの場合は瞬き(Blink)の他に口を開ける(MouseOpen)も作ったので上のように二つのシェイプキーが表示されます。

スクリプトからシェイプキーの値を操作するとAnimatorControllerに顔用のレイヤーを作ったりアバターマスクを作って設定しなくても出来ます。

その分スクリプト側でシェイプキーの値を操作する必要があります。

新しくShapeKeyOperationsスクリプトを作成し、キャラクターに取り付けます。

Startメソッドでキャラクターの子要素のシェイプキーで操作しているメッシュのSkinnedMeshRendererコンポーネントを取得し、それぞれのシェイプキーを0(ベースの状態)に設定しています。

UpdateメソッドではMathf.Sinで‐1~1の値を取得し、それをMathf.Clamp01で0~1の間に調整し、それに100をかけて0~100の間の値を作っています。

Blenderのシェイプキーの値がUnityでは0~100の間で対応されます。

シェイプキーのBlinkの値にこの0~100の値を入れる事で定期的に瞬きをするようにしています。

実行すると以下のようにスクリプトで瞬きをするようになりました。

スクリプトの場合はアニメーションの状態を考慮していないのでどの状態でも一定間隔で瞬きをします。

コメント

タイトルとURLをコピーしました