第14回UE4ぷちコン応募作「アイスクリーム早食い競争」の制作メモ後編です。
ここでは、アイスの構造とかアニメーショとかリザルトとか、雑多に書いていこうと思います。
前回の記事はこちら。アプリのダウンロードリンクもありますので、よかったら遊んでみてください。
アイスの構造
アイスは、地面においてあるやつと手に持つやつの2種類作りました。こちらもキャラと同様に親BPを作ってから種類別にチャイルドBPを作りました。
どうせ2種類つくるのだからと開き直り、地面においてあるアイスのサイズと、手に持ったときのサイズは、ちょっと変えています。地面のほうが少し大きめです。
アイスはスケルタルメッシュにしました。
あまり目立たないですが、手に持った時フタが取れるアニメーションを再生しています。だんだんと減っていくところもやりたかったのですが、作業時間が微妙だったのでやめておきました。
スケルタルメッシュでアニメーションBPと連携するためには、ActorではなくPawnにする必要がありました。
最初Actorで作っていたので動かなかったのですが、ClassSettingにあるParent classの設定をPawnに変えることでなんとかなりました。
手に持つのは、手首のソケットを使いました。ちゃんと手に持つようにソケットの子にアローコンポーネントを置いて、アローの方向で調整しました。ソケット便利。
目立たないですが、右手には木のスプーンを装備しています。
キャラクターのアニメーション
更新は全部アニメーションBPのアップデートにまかせて、Boolの値をインターフェイスで設定するだけにしました。アニメーションBPが毎フレーム、キャラの様子を見ている感じです。
ステートマシンはこんな感じです。サードパーソンキャラクターに元からあったジャンプの流れは削除しました。キャラクターの親BPと連携してるので、プレイヤーキャラもAIも同じ動きをします。
akeytsuでアニメーション作成
グレイマンのアニメーションは、akeytsuを使って作りました。とても楽に作れるのでakeytsuは気に入ってます。UE4のリギングを使うのは学習時間がとれなさそうだったので見送りました。
Discover akeytsu | The 3D animation tool for artists
akeytsuはスケルトンつきのFBXを読み込んでアニメーションが作成できるツールです。なのでまずUE4からグレイマンをエキスポートしました。akeytsuはスケルトンなしのモデルに骨を入れるリギング機能もありますが、今回はグレイマンのモデルをそのまま加工せずに使いました。
エキスポート時のFBXのバージョンは2018にしておきました。一回2016のバージョンでエキスポートしてみたら、足が180度ねじれてしまうという状態になったので、エキスポートし直したりしました。できるだけ最新バージョンに設定する方がよさそうです。
akeytsuにインポート
akeytsuにはあっさりインポートできます。
LOD用のメッシュも複数同時に読み込まれるので、必要ないモノは非表示にしておきます。テクスチャは読み込まれないのでそこはスルーします。アニメーションを作るだけなら別に要らないです。ほぼグレー一色なので。
あとはakeytsu側で、IKにしたりリバースフットを設定したり、アニメーションを作る準備をしてアニメーションを量産していきました。
akeytsuからエキスポート
アニメーションを作ったら、akeytsuからエキスポートします。シーン全体をエキスポートすれば、作ったアニメーションはTake毎に別々になってFBXファイルに入ります。
あとでなにか追加した場合は、Selectionの方を選んでエキスポートすれば、選択したアニメーションだけ書き出せます。
UE4にインポート
グレイマンのアニメーションを追加するだけなので、UE4にインポートするときはメッシュのインポートのチェックを外しておきます。スケルトンはUE4マネキンスケルトンを選択しておきます。
とくに軸の補正の設定も必要なく、普通に読み込めました。
リザルト表示について
最初、リザルトは表彰台にしようと思っていたのですが、これまた時間が微妙だったので仮でつくってた空を写しておくっていうシーンをそのまま使いました。BGMには表彰式で定番の「見よ勇者は帰る」を使うのもいいなと思ったのですが、Youtubeで権利侵害とか言われたらイヤなのでやめておきました(たぶん大丈夫だと思うのですが)。
食べたアイスの個数(スコアとします)をキャラに紐付けたままソートするのと、同率の順位を表示するのは、自分としては地味に苦労しました。いくつか調べた方法を合体させたりシンプルにしたりなどこねくり回しました。
まず、スコアはキャラクターのIDとともにゲーム終了時にリザルト表示用の構造体に入れました。ゲームインスタンス内で処理しました。
その構造体をまずスコア順でソートしました。
ダミーデータで初期化してある配列に、スコアの大きな値の要素を追加してから、末尾の項目を削除するという流れです。プレイ直後の値が、すでに配列内にある要素の値より大きければブレイクしてInsertされるので、末尾の要素を消していけば配列の要素数は変わらず、大きい順で並び替えられます。
次は、同率順位の処理です。
リザルト用の構造体の中に、順位の値を入れる変数を作ったので、その値を書き換えて行きました。配列の一番最初の要素は1位で確定としておきます。
ランキング用の数値を1から開始して、次の要素のスコアが前の要素のスコアと同じ値だったなら同順位とし、違っていたら増やした分のランキングの値にするという判定を繰り返していきました。1位、1位と続いた場合、次の順位は3位になるので、この流れで大丈夫でした。
GetResultData関数の中↓
SetRankingNum関数の中↓
おわりに
色々余談など。
背景のアセットは、マーケットプレイスの「POLYGON City Pack」と「POLYGON Town Pack」を使いました。リアル系の背景も考えたのですが、ライティングのビルドにものすごく時間がかかってしまう(ものによるのかもしれませんが)ので避けました。いろいろとパーツが揃っていたので、抜き出して並べて公園ぽく組み立てました。
タイトルに使っている掲示板と、学校の校庭でつかわれてるようなテントは自作しました。掲示板の中身は、モデルに貼り付けているテクスチャ画像です。
一応、実名っぽい名前を使ったりしているので、念のため応募動画の最後に「フィクションです」って書きました。ちょっと雰囲気が重くなるので、入れておくのは避けたかったのですが念のためです。
あと、アイスのテクスチャもなんかどっかで見たことがあるような印象を受ける人もいるかもしれませんが、実在のものとは関係ありません。
以上です。読んでいただき、ありがとうございます。