第15回UE4ぷちコン応募作「ROTATE BREAKOUT」の制作メモです。後編はグラフィック関連と不具合に対応したことについて書こうと思います。
前回の記事はこちらです。アプリのダウンロードリンクもあります。
(安全ではないアプリという表示が出ると思いますが、「詳細情報」のクリックで実行できると思います)
グラフィック素材について
全部MagicaVoxelを使ってボクセルで作りました。ゲームは全体的に2Dに見えますが3Dです。
あとで色をつけるつもりだったので、色分け用の頂点(ポリゴン)を作るだけにしてシンプルにしました。MagicaVoxelで作られる細長のテクスチャは使用しませんでした。
作業中に、ステージの床だけはでかいサイズ(200ボクセル)を1メッシュで作ってしまったので、失敗したな~と思いつつ進めてました(1メッシュになってることでBP作成では楽でしたが……)。床が回転するので、グリッド的なものは必要だろうと思い、ちまちま線引いていきました。けっきょく床がうるさすぎたので、最終的には点だけにしましたが。
モデルのUV展開は3D-COATの自動展開でさっくり終わらせました。MagicaVoxelからobjで書き出したモデルをUVモデルとして読み込んで、UV自動展開>UVパック>UV適用>モデルエキスポートで終了です。
色はSubstance Painterでつけました。先に必要な色と質感のマテリアルを作ってから、マスクをつけてポリゴンフィルでぽちぽちしていくだけです(このために、MagicaVoxel上で色分けしてポリゴンを作っておきます)。エミッションで光らせるつもりだったので、出力用にEmissiveチャンネルを増やしておきました。
ざっとここまでの手順は、スピーディで簡単なのですが非破壊的なのがちょっと残念で、モデルを修正したいとなったら最初のMagicaVoxelからやり直しです。頻繁に修正があるならば、あまり良くないワークフローだとは思います。私は、修正なんてほとんどせずにささっと素材を揃えたかったのでこの流れにしました。
あとはアンリアルのマテリアルでテクスチャと色を設定しました。SubstancePainterで書き出すテクスチャは、基本的にグレーにしておいて、マテリアル内のVectorパラメータで色を重ねるようにしました。エミッションはTime と sineのノードで強さが変わるようにしました。(Sine と、Sign を間違えて、あれ~動かないな~とかやってたりしました)
途中にClampノードを挟んで、Sineの出力の最低値が0になるのを避けました。
ベースマテリアルは一個だけにして、すべてのオブジェクト用に個別にマテリアルインスタンスを作りました。ラフネスとメタリックは、Substance Painterでプラスチックのマテリアルを元にしていたので、その設定をそのまま使いました。ノーマルマップは全く使っていないのですが一応設定しておきました。
タイトル文字
タイトル文字のモデルもボクセルで作りました。地味に面倒くさい作業でした。タイトル変えようかと何度も思いました。
タイトルは、メインのカメラのピントが合う場所に強引に配置するという力技で表現しました。カメラにはDOFを設定していて、ピントがあう距離を50にしたので、カメラから50cmの場所に縮小して置きました。
文字の回転は、タイマーで一定時間ごとに1文字ずらし、タイムラインとSet Relative Rotation で動かしました。
カメラのDOFの設定はカメラコンポーネントのPostProssesSettings ノードでやりました。ステージの切替時やリザルトに入ったときなど、DOFを変えてぼかしました。
FocalDistanceの値を0にすればDOFは効かず、任意の値を入れればその値以外の距離ではピントが合わなくなって絵がボケます。
MakePostProssesSetingsノードを選択すると、設定項目がずら~~~~っと並び、それぞれの項目にピンを外に出すチェックボックスがあるので、必要なのを選べばOKでした。(設定項目がめちゃ多い)
ゲームのセッティングについて
マウスの操作がメインになり、人によって感覚が違うだろうと思ったのでゲームのセッティングを作りました。スライダーの値は0~1.0のままにして、プレイヤーキャラ側でその値を移動速度の設定範囲内に収めるようにしました。実際の値は、600~5000になっています。
スライダーの表示は、10倍した数字にしています。見た目だけ10倍です。中間が0.5より、5のほうがわかりやすいかと思ってこのようにしました。
回転方向は表現方法を迷ったのですが、CWとCCWにしました。とくにわからなくても、2択なのでどっちかに設定したらわかるだろうと思い、この形にしました。
私はマウスホイールを手前に回したら時計回りになる感覚だったので、デフォルトをそちらにしました。逆の人がいたらすいません、設定してください。
セッティング内容は専用の構造体を作ってスコアとは別にセーブしました。
音について
無料で使えるWEB上のツールを使いました。
sfbgames.itch.io
このゲームの音は全部これで作りました。左側にプリセットなボタンがあるので、爆発音とか1UP音とか選んでランダムに鳴らし、良さげな音を右下のボタンでセーブしていくという簡単なお仕事でした。波形が選べるので、同じ音でも波形を変えるとかなり印象が違ってきます。
ボールが跳ね返ったときの音は、琉球音階(ド、ミ、ファ、ソ、シ)にしました。ツール上には鍵盤があるので、「ド」の音で良さそうな音を作ったら、それの音階を変えながら1音ずつセーブしていきました。琉球音階の音は、ランダムに鳴らしても不快に聞こえにくい音になるかなと思い設定しました(超高速で重なるとちょっと不快に聞こえますが)。UE4のサウンドCueに全部の音階の音をつめこんで、ランダムに鳴らすようにしました。
BGMを入れるかどうか迷ったのですが、無いほうが雰囲気が出ている気がしたので、BGMは入れませんでした。
問題への対処
とにかく、ステージの回転中にコリジョンが抜けることが多かったです。この対処に時間がかかりました。(応募動画の時点では、特に調整してなかったので注意しつつ撮影しました)
ボールが壁を抜ける問題
ステージの回転中は、プレイヤーの他にボールも抜けていくことがありました。ボールが抜けるのは、プレイヤーが壁を抜ける頻度に比べると格段に少ないのですが、それでも抜けていくときはあります。
ミス用のトリガーでステージ全体を囲むように配置して、ミス扱いにすることにしました。(プレイヤー様におかれましては納得できかねることと存じますが何卒…)
プレイヤーが壁を抜ける問題
色々な方法をためしました。まず、プレイヤーが壁の外とか、ブロックに挟まったりとかで動けなくなった時、EscかPキーでポーズメニューに入って、右下のボタンを押せば初期位置に戻せるようにしました。
さらに、プレイヤーの真下にトレースを飛ばし続けて、床の上にいる判定をしました。EventTickはフルスペックでなくても良いと思ったので、0.1秒間隔に設定しました。床から離れたらウィジェットで文字を表示して初期位置に戻すようにしました。
さらにさらに最終的には、ステージが回転中はプレイヤーのフィジックスをONにするということで対処しました。物理状態なら抜けることはほとんどなくなりました。
しかし物理にしたことで、壁に接触していると回転に巻き込まれる形になり身動きがしづらくなりました。あと、微妙に慣性がついているというか、引きずられるような感覚があります。ステージの回転中はそもそも動きにくくなってるので、ヒットが抜けるよりはましかと思って設定しました。
フィジックスの設定は下図の感じです。Linear と Angular の Damping は1以上の値って大丈夫なのかな?と心配になりつつ10とか入れてみました。よくわかってません。
先に、最初から全部物理やってしまうのを試しましたが、ズルズルとすべるように移動したり、勝手に回転するのでカウンターをあてるように多めに回さないとならなくなったり、ちょっと気持ち悪い感じになったので、一時的に物理状態に切り替えることにしました。
プレイヤーがブロックにめり込む問題
これは、ステージが回転していてもしていなくても発生した問題でした。プレイヤー棒を回転しながらブロックに押し当てていくと中にめり込んでいきます。
結局、プレイヤー棒の周りにトリガーをおいてブロックにオーバーラップしたら回転できなくするという制限をつけました。このせいで、ブロックにひっつくような感覚があったり、狭いところを通過しにくくなったりで、操作感覚がイマイチに感じられるのが良くないところです。(物理状態の気持ち悪さと、どっちがいいのかっていう話かもしれません。一人で作ってると、この辺の判断は難しいです)
おわりに
前から考えていた「なんか違うブロック崩し」が実現できたので自分としては満足でした。しょせんブロック崩しって言われてしまえばそれまでですが、元がシンプルなので処理の順番とか流れとかを、より明確に意識できるようになりました。個人的に良い経験値になったのではないかと思っています。