裏 Unreal Engine 4 (UE4) Advent Calendar 2016 21日目の記事です。
UE4の裏っぽいことその2です。
偶然にもsinobuさんに引き続き、キャラクターに関するお話です。こちらは2次元です。
結論から先に言いますと、ユニティちゃんはUE4の教育に向いています。
私も実際、ユニティちゃんのFBXインポートからUE4の勉強を始め、本日このアドカレにネタを書けるぐらいまで成長しています。
後にも記述していますが、ユニティちゃんの素材を通じてUE4で普段触らないであろう機能をたくさん触ったため、非常に勉強になりました。
これほどUE4の機能を学べる3Dモデル素材は滅多にないといいます。
本日はユニティちゃんの素材の一つ、キャンディロックスターをUE4へ移植するお話です。
なんでアンリアルツインズじゃねんだとか、グレイちゃんじゃねぇのかとか意見が聞こえてきそうです
せっかくのアドカレですし、普通の技術ブログみたいに書いてもつまらないので、某アニメを参考に色々と面白おかしく書いてみました。
最初に断っておきます。ネタ検証で徹夜明けし、その勢いのまま書いたのでいろいろとおかしくなってます……。
ここから下は黒歴史確定なので、大目に見てもらえると助かります。
#コハクのまほう-MAGIC OF KOHAKU-
UE4でユニティちゃん表示にはげむ、社畜たちの青春!
私、(勝手に)ゲームを作ります!
ス○ラのまほうの世界に行きたい!!!!
#コハクのまほうとは?
『コハクのまほう』とは、大鳥こはくことユニティちゃんをUE4で使用するとスキルが自然に伸びる現象のことです。
説明する必要もないぐらい非常にかわいいユニティちゃんですが、一部アセットがUnityの機能を利用してキレイに見せているところがあるため、使う素材によっては使用難易度が極端に上がる鬼軍曹と化します。
さてはアンリアルエンジンだなオメー。 pic.twitter.com/AeS0a9xI5V
— しかちゅー (@shikachu72) 2016年12月13日
しかちゅーさんのtwitterを引用させていただきました。
まさしくこんな感じに見えてきます。
その鬼軍曹のアセット名は「ユニティちゃんキャンディロックスター」
その素材はかわいい顔をしてかなりエゲツないしごきをしてくるため、このしごきに耐えたら自然とスキルアップします。
教育にも使えるので一石二鳥です。
今回はUE4のスキルが上がる魔法のようなしごき内容を記載していきます。
#イントロダクション
ユニティちゃんキャンディロックスターがリリースされた日、いつかUE4に移植しようと「やりたいこと」と出会った自分。
ある程度UE4がわかってきて、いざやりたいことをやってみるとキャンディロックスターモデルの移植って大変!
UE4上ではビ〇ーズブートキャンプ並みの鬼軍曹となって教育してくるユニティちゃんと一緒に、色々と苦しみながらも完全移植を目指して頑張ります!
#第1話 スタート地点
##あらすじ
ユニティちゃんキャンディロックスターがリリースされた日、衝撃を受けた自分はこれをUE4に移植してみようと考える。
4月のぷちコン作品へ投稿が終わってから、ある程度操作になれた時、ついにユニティちゃんキャンディロックスターをアンリアルエンジンで表示する決意をする
##作業手順
公式からCandyRockStarプロジェクトをダウンロードしましょう。
ダウンロードが終わったら、早速ユニティちゃんCRSのFBXとテクスチャーをUE4にインポートします。
FBXのインポートは、以下の投稿記事を見てもらえればわかると思います。
UE4でSD版ユニティちゃんを動かしてみる ー Part1 ユニティちゃんをUnrealEngineへお出迎え(インポート)ー
SD版ではありますが、テクスチャーとFBXインポートの設定は一緒です。
FBXの場所ですが、
unitychan-crs-master\Assets\UnityChan\CandyRockStar\CandyRockStar.fbx
にあります。
テクスチャーの場所ですが、
unitychan-crs-master\Assets\UnityChan\CandyRockStar\Textures
にあります。
インポートするテクスチャーファイルは
body_00.tga
body_00_NRM.tga
body_00_SPEC.tga
body_01.tga
body_01_NRM.tga
body_01_SPEC.tga
cheek_00.tga
eye_iris_L_00.tga
eye_iris_R_00.tga
eyeline_00.tga
face_00.tga
hair_01.tga
hair_01_NRM.tga
hair_01_SPEC.tga
skin_00.tga
です。
フォルダの場所がわからなければ、ダウンロードしたプロジェクトのフォルダを開けばAssetsという名前のフォルダがあるので、そこからたどっていってください。
#第2話 たのしい移植
##あらすじ
ユニティちゃんとテクスチャーのインポートを終え、自宅にて楽しい移植作業がスタート。
テクスチャーからマテリアルをとりあえず作成しながら、トゥーンレンダリングの方法を模索する日々。
マテリアルをモデルにあてはめてたユニティちゃんを見て、心がとても満足する。
##作業手順
インポートしたテクスチャーからマテリアルを作って、モデルにあてていきましょう。
そもそもマテリアルすら作ったことのない初心者の人は、以下の画像のように大体こんな感じでやればそれっぽいの作れます。
マテリアルを作成したら、インポートしたCRSモデルに当てていきます。
画像の通りにマテリアルを当てればキレイに表示されます。
ここまではUE4初めてから数日の人でもできると思います。
次からいよいよ本番、散々苦しめられた凶悪なアニメーションの移植作業に入ります。
#第3話 おかずのまほう
##あらすじ
モデルのインポート作業をすべて終え、遂にCRSアニメーションのインポート作業に入る。
インポートしたアニメーションを見たとき、想像を絶するモンスターの出現に唖然とする。
ついに牙をむき始めたユニティちゃんCRSによる圧倒的不具合に成すすべなく殺されようとしていた時、とあるTwitterを見つけ……。
##作業手順
アニメーションをインポートします。
アニメーションが入ったFBXのインポートは、以下の投稿記事を見てもらえればわかると思います。
UE4でSD版ユニティちゃんを動かしてみる ー Part2 ユニティちゃんのアニメーションデータをUEへ適宜インポートー
アニメーションファイルの場所は
unitychan-crs-master\Assets\UnityChan\Animations
にあります。
インポートするFBXファイルは
C86unitychan_003_NOT01_Final.fbx
Hand_expression.fbx
の二つです。
Hand_expressionは指のアニメーションになります。これは第4話で説明するので、いったん置いておきます。
C86unitychan_003_NOT01_Finalが手以外のダンスアニメーションが入ったものになります。
インポートしたC86unitychan_003_NOT01_Finalのアニメーションファイルを開いたとき、予想を超える出来事が待っていました。
##現象(グロ注意)
ユニティちゃんCRSのアニメーションをUE4にインポートしましょう。
すると、こうなります。
肩から胸の部分がモンハンのウカム装備みたいに明らかにおかしくなってます。
どうしてこうなった!!
##原因
アニメーションのFBXを3DMAXで見てみましょう。
もう、誰が見ても明らかですね。
ボーンがおかしいです。どうしてこうなった。
これでは残念なお胸になってしまうのも納得です。
ボーンを直せば解決しますが、残念ながら私のようにボーンの知識が皆無な人だと、これだけでも結構な時間がかかる重労働です。
なので、手っ取り早くUE4の機能で解決できないか調査しました。
##おまけ なぜ、Unityではきれいに表示されるのか
これが発覚した時、当然のように「なぜUnityではきれいに表示されるのか?」という疑問がわきました。
調べたところ、どうやらRigのAnimationTypeにHumanoidを設定しているとUnity内部でいい感じに自動修正してくれるようです。
(もしかしたらAvatarDefinitionも関係あるかもしれません)
ゲームエンジンの素晴らしい機能を見れてよかったです。
これでアニメーションの生産性を上げているんだなーと、一つのテクニックを知ることが出来ました。
##解決方法
ボーン以外の解決手段を調査していたところ、おかずさんのtwitterに行き当たりました。
Unityちゃんライブのアセット、UE4に持ってきたのはいいけど、何故かお胸の辺りの服がこんな感じに…(反対側からの絶景はご自身の目でお確かめ下さい) pic.twitter.com/2sF6YHZqY7
— おかず (@pafuhana1213) 2014年11月5日
まさしくこの現象です!
twitterを遡っていくと、解決手段をつぶやかれていました。
例の胸周りの服の件が解決した。手順は、リグ設定後のアニメーションリターゲットで別スケルトン用のモーションに変換 → LIVEユニティちゃんSkeletonに対して、さらにアニメーションリターゲット。寝る
— おかず (@pafuhana1213) 2014年11月5日
これで意味が分かる人は、ここから先は見なくて大丈夫です。
私のように意味がわからなかった初心者に向けて、どうやって解決したかを書きます。
ユニティちゃんCRSアニメーションの胸周りを手っ取り早く修正していきましょう!
###リグを設定
UE4内部でいい感じにボーンを修正してもらうように、スケルトンにリグを設定します。
ここからは、ユニティちゃんで使用されたアニメーションのみを使うのか、UE4のアセットにあるアニメーションなど汎用的に使いたいかでやり方が異なります。
ユニティちゃんで使用されたアニメーションのみを使う場合は、ユニティちゃん本体のボーンからリグを作成します。
汎用的に使う場合は、Humanoidにリグを設定しましょう。
###Humanoidリグの設定
####1.リターゲットマネージャーを開く
ユニティちゃんCRSのボーンを開き、リターゲットマネージャーを開きます。
リターゲットマネージャー画面にリグを設定という項目があるので、リグを選択を押し、ヒューマノイドリグを設定をクリックします。
####2.ボーンを設定
以下のようにボーンを設定します。かなり面倒ですが、必須作業です。
※この作業はUE4.12で行っていたため、画面が少し古いです
※4.14以降
4.14以降であれば、自動マッピング機能である程度リグ設定を自動的にしてくれるようになりました。
ただし、全て正確にリグ設定してくれるわけではないので、手直しは必須です。
####3.別のモデルを用意し、1~2の手順を行う
もう一体、Humanoidリグを設定したモデル(スケルトン)を準備します。
ここではHumanoidを選択すると自動的にボーンが配置される、ブルーマン先生を使用しました。
####4.インポートしたアニメーションをリターゲット
インポートしたCRSアニメーションを右クリックして「Animアセットをリターゲットする」を選択します。
ボーンを選択したらリターゲットボタンをクリックします。
無事成功すればブルーマン先生のボーンにリターゲットされたアニメーションが生成されます。
ブルーマン先生のアニメーションがかなり気持ち悪いですが、ブルーマン先生は踏み台なので気にしないことにします。
####5. 4で生成したリターゲットしたアニメーションを再度リターゲット
今度はユニティちゃんのボーンを選択して、リターゲットボタンをクリックします。
すると4で生成したアニメーションを、ユニティちゃんのボーンでリターゲットされたアニメーションが生成されました。
これならマーケットプレイスに販売されているHumanoidが設定されているモデルにも、CRSアニメーションを使用することが可能かもしれません。
###ユニティちゃんリグの設定
他のUE4アセットでCRSアニメーションを利用する気がないのであれば、ぶっちゃけユニティちゃんのモデルでリグを設定したほうが楽です。ボーン構造もほぼ一緒です。
ボーンで右クリックし、リグを作成を選択するとリグが生成されます。
通常ユニティちゃんのボーンでリグを作成した場合、以下のボーンをNoneにすればうまくリターゲットされます。
J_L_Sode_D00
J_L_Sode_D01
J_R_Sode_A00
J_L_Sode_A01
J_L_Sode_B00
J_L_Sode_B01
J_L_Sode_C00
J_L_Sode_C01
J_R_Sode_D00
J_R_Sode_D01
J_R_Sode_A00
J_R_Sode_A01
J_R_Sode_B00
J_R_Sode_B01
J_R_Sode_C00
J_R_Sode_C01
J_L_HairTail_00
J_L_HairTail_01
J_L_HairTail_02
J_L_HairTail_03
J_L_HairTail_04
J_L_HairTail_05
J_L_HairTail_06
J_R_HairTail_00
J_R_HairTail_01
J_R_HairTail_02
J_R_HairTail_03
J_R_HairTail_04
J_R_HairTail_05
J_R_HairTail_06
ここまで作ってしまえば、あとはHumanoidリグの2以降の作業と同じです。
CRSユニティちゃんボーンと通常ユニティちゃんボーンの「リグを選択」で、作成したリグデータを選ぶようにしましょう。
これでひとまずアニメーションの修正が終わりました。
Hand_expression.fbxも同様に一部分が崩れてしまっているので、同様の方法で直してしまいましょう。
なぜCRSのモデル移植はあっても、なぜかアニメーションがUE4でやっている人が見かけない理由がわかった気がします。
アニメーションをUE4に移植するのが超絶面倒過ぎて誰もやらないんだなーと。
実際、ここからアニメーションだけで相当面倒な地獄を体験しています。
#第4話 スキルアップ-ブレンドアニメーション-
##あらすじ
何とかアニメーションを修正し、元気よく踊るユニティちゃんを見て心が癒される自分。
暫くアニメーションを観察していると、ふと指が全く動いていないことに気づく。
Unityで確認すると指がちゃんと動いていることに疑問を感じ、プロジェクトを調査する。
すると、そこには指のみのアニメーションが収録されたFBXがあった。
##Hand_expression.fbx
続いて頭を悩ませる自体がありました。
アニメーションを直したにもかかわらず、指が全く動いていません。
原因は第3話で記述した通り、「手、指」と「体」のモーションが別々のアニメーションになっていることです。
この異なるアニメーションを、Unityと同じように合成しないといけません。
ネットを調査したり、JVRH2016で下田さんにコッソリ聞いてみたりと色々やってた結果、今年の7月頃に遂に解決手段を見つけました。
##作業手順
アニメーションブレンドをする方法ですが、ボーン毎のレイヤードブレンドを使用するだけです。
アニメーションブループリントを作成し、以下の画像の通り「手、指」と「体」のアニメーションをボーン毎のレイヤードブレンドにつないで、最終アニメーションポーズにつなぎます。
続いて、「ボーン毎のレイヤードブレンド」を選択肢、BranchFiltersを二つ追加し、BoneNameにそれぞれCharacter1_LeftHandとCharacter1_RightHandを入力します。
ただこれだけです。わかってしまえば単純です。
これで動作のアニメーションはすべて反映しました。
ただし、二つのアニメーションが入ったFBXも表情(モーフターゲット)のアニメーションは一切入っていません。
なので、どうにかして表情を付ける必要があります。
#第5話 トゥーンレンダリング
##あらすじ
マテリアルを作成しているとき、ふと、とあるゲームのトゥーンレンダリングを思い出す。
ユニティちゃんにもトゥーンレンダリングを当ててみたいと思い、色々なブログを調査し始める。
##作業手順
一回おまけを挟みます。
トゥーンレンダリングの調査は、マテリアル作成と並行して行っていました。
この次期で試したのは以下の通りです。
###1.下田式ノンフォトリアル
下田さんが公開しているノンフォトリアルです。最初に試したトゥーンレンダリングです。
アンリアルフェス2015横浜で公開したNPR、トゥーンのアルゴリズムと使い方詳しく解説するよ(*´∀`)う
こちらからダウンロードできます。
手順も書いてあるので、かなりお手軽にできます。
###2.おぎまふ式セルルック
おぎまふさんがブログで公開しているセルルックです。
RoyさんのUEでセルシェーディングも参考に実装しました。
やったことはお二人のブログに掲載されているマテリアルをそのまま組み、私が好きなトゥーンレンダリングになるようパラメーターを調整しただけです。
まだまだ調整不足なので、この先も色々と調整していきたいです。
マテリアルの詳細はリンク先の記事を見てください。
マテリアルの知識が皆無の状態でここまで手軽に組めたのは素直にスゴイと思いますし、こういう技術情報を公開していただけていることに感謝しかありません。
#第6話 アニメーション通知
##あらすじ
アニメーションブレンドが終わり、いよいよ表情の移植作業に入る。
Unityを調べてみると、イベント通知により表情を切り替えていることに気づく。
UE4でも同じことができないか調査をしてみる。
##Unityではどうやっているか?
Unityのプロジェクトを調査したところ、表情はHand_expression.fbxに埋め込まれているアニメーションイベントの通知から行われています。
Stringで渡した引数がAnimatorで指定された名前になっており、それを渡すことで表情を変えているようです。
##作業手順
モーフターゲットの実装はalweiさんのUE4 モーフターゲットを使って表情を変えてみるで詳しく掲載されています。
モーフターゲットのインポートを忘れた場合、FBXを再インポートする必要があります。その時は必ず「Import Morph Targets」にチェックを入れた状態にしてください。
モーフターゲットに値を入れるのは
1.ブループリントのSet Morph Targetノード
2.エディターのカーブからモーフターゲットを選択してキーを打つ
のどちらかです。
今回はアニメーションの時間も長くキーを打つ場所が多いため、時間の節約も込めてUnityと同じ、通知からのSet Morph Targetノード設定で行きます。
アニメーション通知については、右クリック→通知を追加→新規作成で作れます。
ここではdefult、eye_close、smile3、confの四つを作ります。
あとはUnityのタイムラインを見ながら、通知を該当時間に受け取れるように配置していきます。
続いてモーフターゲットの値を設定するため、アニメーションブループリントから通知を呼び出します。
これで通知が来たら表情が変わるようになりました!
しかし、まだ口パクができていません。
この実装作業をしているとき、口パクのやり方は見当もついていませんでした。
時間がかなりかかりそうだと判断したため、髪とか胸とかを揺らす方法を調べ始めました。
#第7話 おかずのまほう その2
##あらすじ
ついにユニティちゃんCRSに表情を実装し、残り作業でやり方がわからないのは「小物や髪、胸をゆらす」と「口パク」のみ。
ふと「ゆらす」ことに関しては、7月時点に髪の毛に物理アセットを入れたところ、髪の毛が激しく動き回る制御不能の気色悪い動きをした上、求める挙動をしないために物理アセットを断念していたことを思い出す。
他にやり方が無いかインターネット上で調べたところ、とあるブログ記事を見つける。
##作業手順
おかずさんのUE4のAnim Dynamicsを使って、グレイちゃんを揺らしてみたを参考にしました。
特定分野の情報はおかずさんからなぜか大量に出てくるので非常に助かります。
揺らしたいボーンすべて実装しました。
この作業をやってる時が時間的に一番大変でしたが、非常に楽しかった覚えがあります。
特に胸がゆれたときは、こんな簡単に実装できるのかと感動すら覚えました。
後ろの髪の毛だけは最大52ヶ所と設定する項目が非常に多く、口パクのやり方に見当がついていない段階で投稿日(21日)にとても調整が間に合わないと判断したため胸と同じ値のままにしました。
※追記 2017/12/11
元記事の画像が消えていたので、設定値を公開します。大体こんな感じに全て設定したので参考程度に。
##おまけ 胸の揺れはVR上で確認するといい
別に変態的な意味で言ってるわけではありません。
揺れ物の挙動はモニター越しで見るより至近距離で見たほうが、めり込み、不自然な動作を確認しやすいってことです。VRであれば至近距離どころか超至近距離で見ることが可能なため、細かい部分の調整に適しています。何より目から幸せが入ってゲフンゲフン
この作業をやってたときはオキュラスリフトを被って確認してました。
#第8話 Unity『口パクなめたらダメだよ?』
##あらすじ
残る作業は「口パク」のみとなったCRSのUE4移植作業。
口パクの実装方法をしるため、再度Unityのプロジェクトを調べはじめる。
キャンディロックスターのスクリプトにそれらしき形跡がなかったため、ヒエラルキーのGameObjectを再度調べると用途不明のコンポーネントがアタッチされていた。
##Unity ソース解析
LipSync.fbxファイルの中身はHierarchyにあるLipSyncControllerの子です。
この構成を見ると不思議なつくりになっています。
中身がGameObjectしかない。スクリプトはともかく、何故かアニメーションが付いている。
アニメーションを見ると、たくさんキーが打ってあります。よく見るとPosition.Zだけ値が変わっています。
fbxの中身を見るため、MayaLTのサブスクリプションを購入しました。
開いてみると、ロケータが横一列に並んでいるだけです。
rsync_Aのロケータを選択すると、タイムスライダに多くのキーが打たれています。
タイムスライダを動かすと、rsync_Aが上下に動いています。z値だけ変動するアニメーションがついているようです。
他のrsync_I~rsync_Oも同じようなつくりになっています。
なぜ5つのロケータに無意味なアニメーションを付けているのか謎でしたが、以下のスクリプトを読んで意味を完全に理解しました。
LipSyncController.cs
public class LipSyncController : MonoBehaviour
{
public string targetName;
public Transform nodeA;
public Transform nodeE;
public Transform nodeI;
public Transform nodeO;
public Transform nodeU;
public AnimationCurve weightCurve;
SkinnedMeshRenderer target;
void Start()
{
target = GameObject.Find(targetName).GetComponent();
}
float GetWeight(Transform tr)
{
return weightCurve.Evaluate(tr.localPosition.z);
}
void LateUpdate()
{
var total = 100.0f;
var w = total * GetWeight(nodeA);
target.SetBlendShapeWeight(6, w);
total -= w;
w = total * GetWeight(nodeI);
target.SetBlendShapeWeight(7, w);
total -= w;
w = total * GetWeight(nodeU);
target.SetBlendShapeWeight(8, w);
total -= w;
w = total * GetWeight(nodeE);
target.SetBlendShapeWeight(9, w);
total -= w;
w = total * GetWeight(nodeO);
target.SetBlendShapeWeight(10, w);
}
}
ソースを引用しました。
このソースでモーフターゲットの値を取得しているのはこの部分です。
```ruby:LipSyncController.cs
float GetWeight(Transform tr)
{
return weightCurve.Evaluate(tr.localPosition.z);
}
これがもし、Aの発音をするようにモーフターゲットを指定する場合、nodeA.transform.localPosition.zからAnimationCurveの値を取得しているということです。
同じようにnodeIからはAの値からtotalを引いた上で、nodeAと同じ処理を行っています。
つまり、
・空っぽのロケータ(Unityだと空のGameObject)をZの位置だけアニメーションさせる
・それをタイマー値として、事前に作成したアニメーションカーブの値を受け取って「あいうえお」発音をするモーフターゲットに設定する
・「あ」以降はtotalから値を引いて口パクの値を調整する
ことで、歌っているように口パクをさせているという作りになっています。
ようやく口パクの仕組みを理解できました。
・追記
口パクのやり方、Wikiに書いてありました。恥ずかしいw
https://github.com/unity3d-jp/unitychan-crs/wiki
十分に睡眠をとった翌日にあっさり見つかるとは……。やっぱり徹夜するものじゃないですね。
恥さらしの意味もこめて、解析した無駄な努力をそのまま消さずに残しておきます。
解析終了した時の私自身の反応です。
笑い声しか出ないよ、これ
— 荻野雄季@クルーズから出荷された豚 (@YuukiOgino) 2016年12月17日
正直発想の範囲外だった。これはマジでUnityスゲェとしかいえない
なんだこのメチャクチャなやり方w
— 荻野雄季@クルーズから出荷された豚 (@YuukiOgino) 2016年12月17日
思いついた人天才だわ
判明したのが深夜1時50分ぐらいなので、完全にテンションがおかしくなってますね。
ともかく私の予想の斜め上を行く実装方法に、これを考えて実装した人は天才だと思いました。
ダンスモーションのアニメーションにモーフターゲットを入れているにもかかわらず、口パクアニメーションをさせていないのは、このダンスモーションファイルが3つあるため、実装に時間がかかりすぎるという点だけだと思います。
これなら一体分の実装だけで、3つのアニメーションに同じ口パクを実装できます。
Unityを分かっている人ならではの作り方だな、と思いました。
しかし、UE4ではこのLipSync.fbxは使えません。
なぜならボーンアニメーションでは無い上、インポートしてもその作り上、UE4に反映できるのは空っぽのシーンコンポーネーションだけで、アニメーションは一切インポートできない仕様だからです。
この事実が深夜のテンションで色々と壊れていた私自身に火をつけました。
久々にハイになったよ、これ
— 荻野雄季@クルーズから出荷された豚 (@YuukiOgino) 2016年12月17日
何が何でもUE4にCRSの口パク実装してやる!
#第9話 はじめての口パク移植
##あらすじ
やる気に火がついたため、勢いで口パク実装の検証を始める!
MayaLTを利用して色々とフル活動!
何が何でも口パクを実装するため、大量のFBXを生み出すがことごとく失敗し、次第に暗雲が曇り始める。
##色々と検証してみる
早速口パクを実装するために色々と検証しました。
結論から言うと、全て失敗しています。以下、行った検証を書いていきます。
###検証その1 LipSync.fbxを改造してトランスフォームアニメーションをどうにかUE4へ
そもそもMayaLTをサブスクリプション買うまで片手で数えるぐらいしか触ったことが無いため、知識が全く無く、どうロケータを改変していいか分かりませんでした。
無知なりにユニティちゃんのFBXを入れてみたり、ヒューマノイドボーンを入れたりと色々あがいててみましたが、結論、自分の知識量では方法がわからず、この検証はあきらめました
###検証その2 タイムラインからキーを打って値を取得する
続いて考えたのが、タイムラインでキーを入力して取得する方法です。
Unityのanimationを見れば、どこにどういう値を入れればいいか分かります。
しかし、これは物凄い量のキーを細かく打つため時間が掛かります。
なにより面倒です。この面倒な作業を仕事をしながら3日以内までに終われる量では無いと判断し、数個キーを打って心が折れました。
###結局不可能なのか?
検証その2を不可だと判断した時には「21日までに口パク実装は工数の時間的に無理かな」とあきらめていました。
この数値が自動的にタイムライン化してくれないかなーと思いながら、別のアドカレで実装しているシナリオのCSVファイルを見た時、ふと思いつきました。
「あれ、これUnityでCSVファイル生み出せばよくない?」
#第10話(最終話) スキルアップその2-CSV-
##あらすじ
ふとしたキッカケでUnityで値のCSVファイルを生み出すことを思いつく。
早速CSVを出力する方法を調査すると、QiitaでCSV出力の方法が記載されていた記事を見つける。
記事の通りにスクリプトを改造し、生成されたCSVファイルをUE4へインポートを試みる。
##実装内容
UnityでCSVファイルを生み出す方法は、以下の記事に書いてありました。
この記事の内容を元に、スクリプトを改造しました。
以下のスクリプトはOのモーフターゲット値をCSVへ出力する形になっています。
float time = 0;
void LateUpdate()
{
var total = 100.0f;
var w = total * GetWeight(nodeA);
target.SetBlendShapeWeight(6, w);
total -= w;
w = total * GetWeight(nodeI);
target.SetBlendShapeWeight(7, w);
total -= w;
w = total * GetWeight(nodeU);
target.SetBlendShapeWeight(8, w);
total -= w;
w = total * GetWeight(nodeE);
target.SetBlendShapeWeight(9, w);
total -= w;
w = total * GetWeight(nodeO);
target.SetBlendShapeWeight(10, w);
// 現在時刻を更新
time += Time.deltaTime;
// CSVファイルを書き込み
createCSV(time.ToString() + "," + w.ToString());
}
/**
* CSVファイル作成
*
* @param txt CSVに書き込む内容
*/
void createCSV(string txt)
{
StreamWriter streamWriter;
FileInfo fileInfo;
fileInfo = new FileInfo(Application.dataPath + "/LipsOCurveFloat.csv");
streamWriter = fileInfo.AppendText();
streamWriter.WriteLine(txt);
streamWriter.Flush();
streamWriter.Close();
}
この状態でゲームプレイすると、以下のようなCSVファイルがプロジェクトフォルダに生成されます。
※画像はわかりやすいようにデスクトップに置いただけです
作成済みの場合は一行書き込みます。
createCSVはLateUpdateで決まったフレーム単位で定期的に呼ばれるため、自動的に口パクのCSVデータを書き込んでいくという仕組みです。
CSVの配列データはTime, Numみたいな感じです。
0.0001,0
0.0021,0.011
……
ユニティちゃんがダンシングしている間は暇なので、カップラーメンを作るなり、ユニティちゃんと一緒にダンシングするなどして時間をつぶしましょう。ちなみに自分はVR空間でユニティちゃんとダンシングしてました
ゲームプレイ上でのユニティちゃんのダンシングが終わったら、ゲームプレイを止めるかUnityを強制終了して書き込みを止めます。
「A」「I」「U」「E」「O」の五つのCSVファイルを生成し、UE4へインポートします。
データの形式は「FloatTable」です。
CSVのインポートの仕方はヒストリアさんのブログ、[UE4] CSVデータを扱う方法 CurveTable編などに詳しく載っています。
「A」「I」「U」「E」「O」の五つのCSVファイルを、UE4へインポートしました。
ユニティちゃんキャンディロックスターのアクターブループリントを生成して、処理を書きます。
アニメーションの時間分のタイムラインを生成し、モーフターゲットにセットします。
無事、口パクが実装できました、わーい!
最後、BGMを鳴らすタイミングをアニメーション通知で知らせるようにすると、ほぼ完璧に近い形で移植が出来ました。
#エンディング 成果物
成果はYouTubeに動画でアップしました。
後は髪の毛が自然な動きに近づけば、より素晴らしいキャンディロックスターのダンスアニメーションになるので引き続き頑張っていきます。
ステージが移植されてない? ひょっとしてユニティちゃん専用ステージInfinityBlade:GlassLandsのこと?
鬼軍曹、キャンディロックスターで新しく学んだUE4の機能は
・ブレンドアニメーション
・アニメーションリターゲット
・モーフターゲット
・CSVインポート
・Anim Dynamics
・アニメーション通知
・おむねのゆらしかた
になります。
苦労してやり方を発見したため、スキルアップは十分すぎるほど得たのが嬉しかったです。
#結論
ユニティちゃんキャンディロックスターはUnityで使いましょう。
間違っても軽い気持ちでUE4で表示してはいけません、こちらが想定していないことの現象解決に死ぬほど苦労します。
それでもUE4で元気に踊るユニティちゃんキャンディロックスターを見たいという人だけ、挑戦していただければと思います。
鬼軍曹にしごかれたい方は、頑張ってキャンディロックスターを移植しましょう。
UE4でもこれだけ苦労したので、Unity以外のエンジンではかなり苦労すると思いますが、苦労する分、解決した時の学習効果は相当なものだと感じているので、キャンディロックスターを他のゲームエンジンに表示するのはありだと思います。
明日はBlackMa9さんの「プラグイン(C++)でMaterial Nodeのピン接続する話」です。
お楽しみに!
© Unity Technologies Japan/UCL