見出し画像

【Blender&Unity】Unityでシェイプキーを動かす

キャラに表情をつけたい

「Unityでシェイプキーを動かす」なんざ今どき腐るほど情報が出てくると思うけれど、いざ自分でやってみたらハマりどころが色々あったので、個人的な備忘録として残しておきたい。

とりあえず3Dモデルにモーションをつける手段はなんとなく理解できてきたが、巷に転がっている3Dゲームなんぞを眺めていると、キャラクターがひたすら無表情ってこた無いよねという話。まばたきすれば、喜怒哀楽もある。

こないだVRMを作った時はBlenderでシェイプキーを作っとけば、ビューワーの方でいい感じに瞬いたりリップシンクしてくれたが、これをUnityで作った自前のゲームとかで動かすにはどうすりゃええねん…って話。

なので、今回は「Blender上で作ったシェイプキーを、Unityでいい感じに動かす」というのを目標に色々作っていく。

SDキャラを作る

画像1

既存のキャラを使っても良かったのだが、顔でかくないと表情よくわからん気がする。という事で、今回はSDキャラで作ってみる事にした。ゼロから作ると時間が掛かるので、フリーで配布されている素体を改造していく。どうも髪の毛が苦手すぎるので、アニメ髪支援アドオンの練習がてらやね。

画像3

カーブを弄り回しながら我流でやっているのだが、何回やっても後頭部がぺったんこになるんだよなぁ・・・。髪の毛は髪の毛で、ちゃんと作り方を勉強した方が良いのかもしれない。

まあ、今回の主題はそこじゃないので全力でスルーしていく。こういう所で詰まると、無限に時間を吸われちまうからな。

画像4

ついでにもう一匹、タンクトップくんを作る。Eeveeでメッシュの表示がドチャクソバグるんだが原因が分からんので放置。法線の向きも合ってるし、Cyclesだとちゃんと映るんだけどなぁ…謎い。

画像2

ちなみに、今回の服装は某オンラインゲームコミュニティサイトの初期アバターをモチーフに作成した。インターネット黎明期を駆け抜けてきたおっさんならば、こいつらを知っているはずだ。無課金は正義ィ!

シェイプキー(ブレンドシェイプ)を仕込む

画像5

Blenderでいつもどおり頂点テキトーにいじってシェイプキーを仕込む。ここまではOK。あとはこれをFBXにしてUnityに入れたとき、どうやってシェイプキーを呼び出すかだな。

画像6

Unityに取り込んでみたら、「SkinnedMeshRenderer」とかいうコンポーネントに「BlendShapes」という項目があった。スライダーを動かすと、たしかに頂点が動く。Blenderでは0~1だが、Unity上だと0~100になる。こいつをスクリプト上で変更すれば、いい感じに表情も変わるのではないか?

画像7

という訳でさっそく、Boltで実装。GameObject.GetComponent経由で、SetBlendShapeWeightを呼び出してやる。引数のindexは、インスペクタ上で見たBlendShapesの番号(indexじゃなくて名前で指定できれば便利なのになぁ)。valueはさっきスライダーで設定したのと同じ0~100のfloat値だ。

これで行けるやろ!と思って再生してみると、Weightに何をぶちこもうが、キャラクターはひたすら無表情のままである。なんでや!と思ってプレビュー再生中にインスペクタ上のスライダーを触ろうとするも、そもそもスライダーが動かせない。(停止中だったら動かせる)

なんでや…とネットの海を泳いで調べたところによると、「Blenderのシェイプキー作る時に相対のチェック外すといいよ」という情報を見つけた。理屈はよくわからんが、とにかくそういうことらしい。

画像8

ならばワシも外してやろうじゃないか…「相対」のチェックボックスを!

これで表情が動くようになった!と思いきや、よく見たら動かした時に一部の面がバグってる。そして再びネットの海へと漕ぎ出す羽目に。

どうやらBlenderの吐き出すFBXのブレンドシェイプには法線情報が含まれないとかで、Unity側がいい感じに計算して帳尻合わせようとした結果、不運(ハードラック)と踊(ダンス)っちまったらしい。←よく分かってない

画像9

なのでモデルのインポート設定でBlendShapeNormalsをNoneにしてApplyしておく。これで万事OKだわ!

まばたきをさせる

だいぶ苦労したが、ようやく表情を動かせるようになったので、瞬きを実装してみたい。今回は、こちらの記事を参考にまばたきスクリプトをBoltに起こしてみた。

画像10

開く/半目/閉じる間隔を、それぞれ変数で持たせとく。

画像11

シーンが開始したらopenEyeイベントを起こして、Weightを0に設定して目の周りをデフォの開いてる状態にしとく。そこで一定時間待機したら、closeEyeに遷移。

画像12

closeEyeイベントでは、ウェイト40(半目)にしてちょっと待って、ウェイト100(全閉じ)にしてちょっと待って、またopenEyeに遷移…てな感じに、延々と繰り返してやる。これで、まばたいてる感じになってくれるはず。

成果物

だいぶぎこちないが、とりあえず成功。

口をパクパクさせながら目を動かして、ジェスチャー的なモーションも再生させてみた。どうやらブレンドシェイプを複合させても大丈夫そうだ。

しかし、実際にゲームを作ろうと考えた場合、これを全部プログラムでベタ書きするのは大変そうだなぁ。次は、会話イベントを作れるアセット(宴あたり)を組み合わせて、会話中にモーションだとか表情を変える処理を楽に呼び出せないか試してみるか。

この記事が気に入ったらサポートをしてみませんか?