気づけばツール漬け

3D,2Dのツールを色々使ってみた記録を書いていきたいです。

「花咲かGrayちゃん」制作メモ キャラ・その他編

f:id:mi-zmix:20200406221303p:plain

第13回UE4ぷちコン応募作「花咲かGrayちゃん」制作メモです。UE4は4.24.3を使いました。
今回のは、第8回応募作の「猫缶クライシス!」で使った自作ドット絵を再利用しました。
テーマの「さく」で、真っ先に「花咲じぃ(略」が浮かんだので「花がだんだんと咲いていく」という過程を見せるには、ドット絵ならやりやすいし制御もしやすそうと思いやってみました。
3Dだと結構面倒な絵面しか浮かんでこなかったので、個人的には避けて正解だったかもしれません。


応募動画はこちら。

www.youtube.com

ゲームはパッケージにして、個人のDropBoxへアップしました。
応募時の動画は変えていませんが、パッケージにした内容は少しアップデートして、背景(遠景)を追加しました。河川敷のイメージで作っていたので、背景が入ることでようやく説得力が出た気がします。

drive.google.com


Win10で動作確認しました。
出どころ不明のアプリと怒られるかもしれませんが、詳細情報からのメニューからなら
動くと思います。


目次

 

 

キャラクター絵について

Grayちゃんのドット絵ですが、今回の制作用に攻撃パターンをいくつか追加しました。あと、色を整理して16色に収めました。とはいえ、UE4にインポートすると普通にRGBのカラーになってしまうので意味はないです。ただのこだわりです。

f:id:mi-zmix:20200406221656p:plain
追加したドット絵パターンのフリップブックは、作成時に15FPSで統一して各フレームの間隔で再生スピードを調整しました。ただ、攻撃の動作は比較的素早く動かさないとイライラしてしまう事があるので、できるだけ無駄はなくしました。実は15FPSでも遅いのかもしれません。(アニメパターンを割りすぎたとも言えるかもしれません)
f:id:mi-zmix:20200406221840p:plain
灰をまく動きとキックの動きを、それぞれ3パターンずつ作りました。連続攻撃してる感じがほしかったので、ここはがんばりました。毎度毎度ですが、自分の操作に合わせて動きがつくと、かなりテンション上がります。

キャラクターのBPや設定

キャラのスピードや重力の設定なども調整しました。
今回の制作を始める前に猫缶をひさしぶりに遊んでみたら、そのスピードに自分でも驚きました。あのピーキーさは今回のゲームには合わないので、比較的ゆっくり動くようにしました。

キャラの動きでは、猫缶のときに作った、アニメーション切り替用の関数などを再利用しました。UpdateAnimationイベントは、Tickにつないで呼び出しています。

f:id:mi-zmix:20200406222938p:plain

AnimStateMachine関数の中は攻撃の動作が加わったので、ブランチがけっこう多くなってしまいました。今回はダメージがないのでまだ良い方なのかもしれません。というか、ダメージも含めた場合は別なやり方が必要なのかもしれません。
↓AnimStateMachine関数の中の全体図。

f:id:mi-zmix:20200406223006p:plain

コラプスノードの出口をわざわざ分けているのは、中でいくつに分岐しているのかわかるようにするためです。

灰をまく動作

灰をまく動作とキックは、各フリップブックの再生時間が、そのまま攻撃用の時間となるように設定しました。途中キャンセルが必要なほど複雑なアクションではないので、全部の絵が再生されるように設定しました。
コンストラクションスクリプトで、フリップブックの再生時間を取得して変数にSetしました。

f:id:mi-zmix:20200407000348p:plain

攻撃入力は、連打を防ぐためにDoOnceを通しました。

f:id:mi-zmix:20200407000855p:plain

攻撃の回数を数えて、スイッチで3段階に分岐させました。(0段階目は無視します)
攻撃1回分のフリップブック再生時間のタイマーをセットして、イベント呼び出しをDoOnceのリセットにつなぎました。これによって、攻撃一回分が終わるまで次の攻撃入力を受け付けなくしました。

f:id:mi-zmix:20200407000740p:plain
さらに、灰を出すタイミングを設定するため、フリップブックの再生時間から、灰を出す瞬間までの時間(AdjustValue)を引き算し、その瞬間に灰をスポーンしました。灰はProjectileMovementで飛んでいきます。その後の残り時間分ディレイして一回分の攻撃としました。
Ash Spawnマクロの中はこんな感じです。キャラクターの向きを見て、X軸のオフセットを変えてます。

f:id:mi-zmix:20200407001642p:plain2回め3回目の攻撃も同様に作りました。
3回攻撃したら少し時間をおいてから、次の攻撃が可能になるようにしました。

f:id:mi-zmix:20200407002042p:plain

途中で攻撃をやめた場合、攻撃回数をリセットしてまた1からの攻撃になるようにしました。このときすぐに次の攻撃ができてしまうと、連続攻撃に対して不公平なので、攻撃をやめた場合の判定は長めの時間に設定しました。

f:id:mi-zmix:20200407002353p:plain空中で灰を出せるようにもしました。空中時の重力の値を少し弱くしています。このおかげで、空中で灰を出している間に2回めのジャンプ入力をすることで、ハイジャンプが可能になりました(バグを裏技と言い換える手法)。

キック動作

柵の左右どちらかにオーバーラップしてるときだけ、キックが出るようにしました。マクロの中で、プレイヤーへ「キックに変える」通知を送ってます。

f:id:mi-zmix:20200407002850p:plain

キックも灰をまくのと同様に、DoOnceとタイマーからのイベントで一回づつに制限しました。キックの場合はスフィアトレースを出して攻撃判定にしました。

f:id:mi-zmix:20200407003254p:plain

f:id:mi-zmix:20200407003431p:plain

トレースはキャラから出たあとその場から動いていないのですが、柵が背景と一緒にうごいているため、相対的に前に飛ぶ感じになりました。たぶん複数の柵を隙間なく配置すると、突き抜けて当たっていたかもしれません。
ApplyDamageで柵と通信し、柵の中で攻撃回数を数えて、だんだんと
壊れて見えるようにしました。ダメージの数値は未使用です。しかし、0にしてしまうとダメージのイベントが発生しないので適当な値を入れておきました。
これは余談なのですが、キックの操作ボタンを灰と共通にしたのは、できるだけ押すボタンを減らしたかったからなのです。しかし、自分で作っておきながら、ゲームパッドで操作してると時々ジャンプのボタンと間違えるという脳内バグがおきました……。
「ひょっとして、操作は役割ごとにボタンを完全に分けた方が良いのか?」 と、ちょっと迷ったりしましたが、3個のボタンを使い分けるのは、それはそれで難しいことだと思うので、今の仕様のままにしました。
どっちが良いのだろう……。

2段ジャンプ

ジャンプは2段まで可能にしました。2段にする設定はキャラクターのJump Max Count を2に設定すれば良いだけなので簡単でした。

f:id:mi-zmix:20200407221015p:plain

今何段目のジャンプなのか、JumpCurrentCountで取得できます。2段に設定した場合、3になるとジャンプが終わるようです。

f:id:mi-zmix:20200407221215p:plain

その回数を見て、2段目になったときにフリップブックを切り替えて、ついでにちょっとしたエフェクトも出すようにしました。

攻撃エフェクト

エフェクトは、キャラクターのとは別のフリップブックとして作成し、同時に動かすようにしました。
エフェクトをキャラクターの絵に描き込んでしまうと、基準となるスプライトのサイズが変わってしまうので、あとから付け足す方法にしました。サイズが変わるとエフェクトが関係ないやつも含めて、全部のスプライトとフリップブックの設定し直しになるので避けました(ピボットがずれてしまい、調整が面倒です)。
エフェクトを分けておけば、あとから別の絵に差し替えることも可能なので、分けるほうがメリットはありそうです。

f:id:mi-zmix:20200407221552p:plain

エフェクトは、キャラとは別のEnumを作ってフリップブックを切り替えました。キャラの攻撃動作を選択するのと同時に、エフェクトも選択しました。左がキャラの動きで、右がエフェクトの選択。

f:id:mi-zmix:20200407221720p:plain

こちらは、AnimStateMachine関数の中の、攻撃用コラプスノードの中身。

f:id:mi-zmix:20200407221905p:plain

エフェクトが出ないところでは「ナシ」の状態を設定しました(何もない透明なフリップブックのパターンを設定します)。これがないと、一回出たエフェクトがずっと出っぱなしになってしまうので必要でした。

f:id:mi-zmix:20200407222001p:plain

灰エフェクト

灰はプロジェクタイルで斜めに打ち出して、重力で落ちるようにしました。
最初に灰を飛ばしたとき、逆側を向いてもX軸プラス方向にしか飛ばないという状況になって、なんの設定が悪いのかよくわからない状態になってました。
キャラの向きを変えるのはローテーションでやってるはずなので、そのままの設定で逆側にも飛んでくれるだろうと思っていたのですが、そういう動きにはならず……。
なので少々強引ですが、キーの入力値がマイナスになってたら、逆側に飛ばす用の設定に変える処理をしました。このせいで、左側を向いたほうが灰がより遠くに飛んでいるかもしれません(または逆か)。

f:id:mi-zmix:20200408000246p:plain

フリップブックはデフォルトでループ再生になっていて、エディタ上で切り替えられない(設定するところが見当たらない)ので、SetLoopingでループしないように設定しました。
フリップブックの再生時間を取得して、それをそのままSetLifeSpanに設定します。これにより、一回再生したら消える動作になります。

f:id:mi-zmix:20200408000458p:plain

地面とのヒットは判定していません。地面をぬけたり、壁越しに灰をあてたりできるので、これはこれでよいかと思い、そのままにしました。ルートの短縮ができる場合もあるので、本数稼ぎでやってみてください。

UIボタンについて

今回どうしてもやりたいと思ったことの一つが「ボタンをゲームパッドやキーボードで動かせるようにする」ことでした。
調べてみると「フォーカス」と「ナビゲーション」を使えばできそうということがわかりやってみました。
とはいっても複雑なことはさせず、キーによって上下の項目を切り替えるだけにして、ボタンの数も極力減らすようにしました。
フォーカスをとりなおしたり色を変えたりという設定を、各ウィジェット毎に作っていくのが面倒そうと思ったので、ボタンとその動きを一つのウィジェットにまとめました。それを各場面ごとにAddViewportして、その場面にあわせたボタンテキストに変えるという方法でやってみました。

f:id:mi-zmix:20200410120717p:plain

各場面を区別するために、GamePlayStateというEnumを作り、それをもとに各ボタンのテキストを設定しました。今回のゲームはレベルを1個だけにして、ゲームの状態をEnumで切り替えるという方法をとったので、それをそのまま使いました。

f:id:mi-zmix:20200408002131p:plain
まず、ボタンの背景画像は全部透明にしてテキストだけが見えるようにしました。
最初のフォーカスをボタン1に合わせるようにして、フォーカスが合っているボタンのテキストの色とサイズを変えました。あとついでに音も出すようにしました。

f:id:mi-zmix:20200408001332p:plain

f:id:mi-zmix:20200408001453p:plain
ボタン以外の場所をクリックしたとき、全部のボタンのフォーカスが外れて戻らなくなる問題があります。それを回避するために、背後に画面全体を覆う形で透明なボタンを配置しました。(Youtubeの動画で見た方法なのですが、どの動画だったのか忘れてしまいました……)
背景を全部ボタンにして、クリックしたときにフォーカスをボタン1に戻すように設定しました。このボタンは、操作説明を閉じる時にも使いました。

f:id:mi-zmix:20200408001723p:plain
GamePlayStateのEnumの切り替えはプレイヤーコントローラーで行いました。ウィジェットをクリエイトするのもプレイヤーコントローラーでやってます。このため、プレイヤーコントローラーの中がけっこう大きくなってしまいましたが……。
ボタンが必要な場面は、「タイトル」「リザルト」「ポーズ時」だったので、そのときのCreateWidgetノードでEnumを渡すようにしました。ボタンのウィジェットは、場面が変わるごとにクリエイトとリムーブをしています。

f:id:mi-zmix:20200408002730p:plain

各ボタンのクリックイベントは、Enumの値でスイッチして、プレイヤーコントローラーにあるインターフェイスのイベントをつなぎました。

f:id:mi-zmix:20200408002926p:plain

プレイヤーコントローラー側で各処理をさせました。

f:id:mi-zmix:20200408003141p:plain

f:id:mi-zmix:20200408003307p:plain

 

以上です。

次は、背景について書こうと思います。

書きました。

mi-zmix.hatenablog.com