【第4回】滞空能力・ラピッドブースト実装

ロボゲーって基本的にボタンが足りないと思う。僕です。
前回は「ブーストモード」によって地上の挙動を変化させるところまで実装しました。今回はブースト中の滞空能力と、瞬発的な移動を実装します。

ブーストモード中に滞空力を得る

もったいぶらずに動作の様子を。

画像1

まずは歩行モードでジャンプ。上昇と下降がほぼ同じ速さです。

そしてブーストモードをオンにしてジャンプ。ちょっと分かりにくいですが落下速度が減少しています。
この効果はジャンプのみならず、高台などから落下した時にもかかります。

ニートなのか社畜なのか分からない方のブループリントを参考にしました。と言うかパクりました。

まずはブーストモードの切り替え処理。イベント呼び出し後にステータスをセットしているところまで、まんまですね。

画像3

滞空・滑空の処理はマクロに畳んでおきました。

画像2

これもほぼそのままです。
変更点は発生条件に〔Is Falling〕を加えたところです。これは「キャラクターが設置していない・空中にいる状態」をブーリアン値で取得するノードです。パクりもとい参考元のままだと、急な坂を滑り降りている場合にも上昇力が発生するかも知れなかったので。

ちなみに、今回のプロジェクトの大部分がこちらを参考元にしています。
挫折してしまったのか、1年以上更新が途絶えているのが残念です……。アンタの分まで僕ががんばるますぞ!


(前提1)「ラピッドブースト」とは?

英語表記では「Rapidly Boost」、地上および空中で瞬発的な平行移動をする機能です。『アーマードコア4』で言う「クイックブースト」、『V』系統で言う「ハイブースト」にあたります。
あえて別名にしたのはどっちともちょっと違う動きにしたかったからです。

実装……その前に

またこちらを参考に作っていきますが、ちょっと仕様を変えたいというのと、この通りに組むとある問題が発生するので、色々と周辺の処理から手を加えていきました。

ボタン不足への配慮

前書きの通り、『アーマードコア』のようなロボゲーはゲームパッドですとボタン不足に陥りがちです。キーボード・マウス入力にしても、使用キーが増えると誤操作が起こりやすくなりますし、Shift キーや Ctrl (Command) キーを多用すると手が攣ります。

そこで今回のプロジェクトでは、ジャンプとクイックブーストを同じキー・ボタン入力にしようと考えました。
ボタンを短く「タン」と押すとクイックブースト、ちょっと長押しするとジャンプ、そんな仕様にしてみます。

長押しと短押しの切り分け

先人の知恵はどんどん活用していきましょう。

ここに紹介されているマクロをそのまま実装しました。

画像4

はい。これで同じボタンの押す長さによって動作の切り分けができました。
長押しの時間を「0.18秒」に設定しているのにはちょっとした理由がございまして、フレームレートが 60FPS だった場合 1フレームは約 16.7m 秒です。なので60FPS基準で考えるなら 16.7m秒 より長くないと判定が取れません。
ボタン入力の反応速度、さらに人間の手の動作速度を考慮して、少しゆとりをもたせつつ、何度もテストプレイして違和感が出なかった時間が 18m 秒という訳です。
ただこの値は個人による体感差もあるでしょうから、いずれは変数化してカスタマイズできるようにしたいですね。

(前提2)ラピッドブーストに求める挙動

『アーマードコア4』系のクイックブースト、および『V』系のハイブーストは前後左右の平行方向に加速力を得る機能です。
ケチを付けるつもりはないんですが、専用のブースターを搭載する『4』はともかく、『V』のものはあまり現実的に思えないんですよね。
と言うのも、『V』は滞空・グライドブースト(長時間の水平飛行)・ハイブーストを全て機体背部にある2つのブースターユニットで実現している訳ですが、どう考えても機体を火あぶりにしています。特に後ろ方向へはどうやって推力を得ているのかも謎です。
快適にプレイできれば細けぇこたぁいーんだよ! とは思いますが、ちょっと考え物。
(2020/10/05追記:よく見たら機体前部にもブースター付いてました……クサしてすみません)

そこで、今回のプロジェクトで実装する「ラピッドブースト」は若干上昇方向へ推力が掛かる仕様にします。平行にダッシュする感じではなく、放物線を描いて飛ぶイメージです。
ジャンプボタンと共用なのはこれもあってのこと。
実際の動きはシリーズ初期から『3』系まで続いた伝統のピョンピョンブーストに近くなります。

ではこれを実現するにはどうしたら良いでしょうか?

〔Launch Character〕で飛ばせば良い

ローカライズに定評のある公式ドキュメントですが、あまり使われないノードに関しては怪しい翻訳が散見されます。これもその1つ。
Launch は「起動」ではなく「打ち上げ」です。

〔Launch Character〕はその名の通りキャラクターを上に打ち上げるためのノード。主にジャンプ台で使います。
検索すると二段ジャンプによく使われるという記事が出てくるんですが、Characterコンポーネントには多段ジャンプ用の設定が既にあるんですよね。

画像5

「Jump Max Count」を2以上にすれば空中ジャンプができる。

実際の使用例や記事の作成日を見ると、以前のバージョンではこの設定が無かったのかも知れませんね。
ちなみに「Jump Max Hold Time」の値を上げると、ジャンプ入力を受け付ける時間が延びます。入力が続く限り、ジャンプ時の初速(CharacterMovement コンポーネントで設定可能)で上昇が可能になるので、初期『AC』~『4』系のようなブースト上昇は簡単に実装できます。

〔Launch Character〕ノードに話を戻しますが、取り扱いに少し注意点が。

1. 基本的には「打ち上げる」ためのノードだから「打ち出し」は難しい。
このノードはXY(平行方向)への加速も入力できますが、Z(上)方向への加速度が指定されているのが前提になります。たとえば地上でのダッヂ移動に使用する場合には一時的に対地摩擦係数を0にし移動完了後に戻すなど、ちょっと複雑な処理が必要になります。

2. ストレイフランが可能になってしまう。
「ストレイフラン」とは、斜め移動する際に通常速度の √2(約1.4)倍の速度が出てしまうことです。シューティングなど自由移動ができる2Dゲームでよく問題になりますが、古い3Dゲームでも起こる現象でした。

この記事では『DOOM』『Half-Life』が例示されていますが、僕が体験したものだとロクヨンの『パーフェクトダーク』ですね。恐らく同じゲームエンジンを使っている『007 ゴールデンアイ』でも再現できるかと。
〔Add Movement Input〕ノードではこの問題に対応していますが、1.の例のような使用例で単純に〔Get ~ Vector〕* 入力で移動方向を指定すると「ストレイフラン」が起きてしまいます。
〔Set Actor Location〕ノードを使用した移動にも同様の問題が発生します。

「ストレイフラン」対策

まずここから着手しなければいけません。
斜め移動の最適化には SQRT(三平方の定理)を使うのが鉄板ですが、今回のプロジェクトはゲームパッドによるアナログ入力も考慮するので、少し工夫が必要です。

こちらのコードを参考にブループリントで実装してみました。

画像6

長え!!
……まあどういう処理をしているのか可視化したかったのでブループリントに起こした訳ですが、こうした関数の実装はC++で直接書いた方がずっと速いですね。
あ、さらっと「Float *= Float」の関数も作っておきました。

画像7

ブループリントは視覚的にフローが分かりやすい反面、逆に単純な計算には弱いですね。(+= とか /= とかは標準で用意してくれよ……)

いよいよ実装

前置きが長くなりましたが、ラピッドブースト(略:RB)を実装しまふ。

画像8

まずアナログ入力を先ほどの補正関数に通して、キャラクターのZ軸の向きに掛け、合算。これでワールド座標に対してどの向きに入力があるのか得られました。
こいつを作成した〔Rapidly Boost〕マクロに送ります。

画像9

マクロの中身。コイツもクソ長なので、コメントを付けているブロック毎に紹介します。

画像10

開始早々に〔Do Ones〕。「ここから先は一度だけ実行しますよ」というノード。コメントに書いてある通り、連打ができないようにするために使ってます。

その後に『V』系の「溜め」が欲しかったので、一時的に速度を落とします。変数の数値は置いといて、〔Vector Clamp Size Max〕で速度の最大値に上限を付け、ブースターの「溜め」に必要な時間待つ。

画像11

コメントの通り、ブーストモード中にRBを噴くと滑空機能のせいでとんでもない速度で上にすっ飛んでいくので、一旦ブーストモードを切ります。

歩行モード中に発動した場合、一時的に摩擦係数を0にしています。コメントと置いてある変数は気にしないで下さい。なんでこうするのかと言うと、斜面でRBの効果が切れにくいようにです。それでもデフォで置いてある階段には引っ掛かるので、どうにかしたいところです。(効果切れまでほんの少し地上から浮かせておくとか?)

で、キャラクターの移動加速度にRBの出力速度をセット。これも地上用ですね。本当に必要かは未検証ですが。

画像12

方向入力が無い=スティックがニュートラル状態のときに処理を分けます。

1. 入力があったら

画像13

引っ張り込んできた入力方向に、上昇力を加えて Launch!
上昇力の計算式はまだ検証中です。今の仮ステータスだとこんな感じで丁度良くなりました。掛ける値を大きくし過ぎると飛ばないし、小さくするとどんどん上昇してしまいます。

2. 入力が無かったら

画像14

基本的にはキャラクターの前方にRBします。
ただし地上に居る場合はジャンプするようにしてみました。テストプレイを重ねる内に、ちょっとした段差を登りたい時に入力が速くてRBに化けるのがストレスだったためです。ジャンプになった場合は変更したパラメーターを戻して、最初の〔Do Ones〕のリセットへ流れます。
(スクショ時点で加速度の変数を間違えてました。てへぺろ)

画像15

パラメーターを再セットする終了処理。即座にパラメーターが戻らないように、最初に一度クールタイムの35%ぶん〔Delay〕を通してます。
再セットしたら残りの65%をまた〔Delay〕して、〔Do Ones〕のリセットに戻る。

これがラピッドブーストだ!

画像16

なんかビミョー……と思ったそこのアンタ。アンタが正しい。
高速移動手段にはなっているけど、実際のところちょっと微妙。ただ演出的な理由が大きいんじゃないかなと思う。

マネキンだし、ジャンプと同じモーションだし、ブーストの火も無いし、音も無いし。

そうそう、あとカメラだね!

おわりに

と、言うわけで次回はカメラ演出を加えるよ。
でも同時並行でメカデザインも進めてるから、ちょっと遅くなると思います。メカとか……パースとか……もう、もうね……助けて……。

が、ががが……がんばるます!!

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