Unity公式チュートリアルSurvival Shooter WITH PK Chapter.20「弾切れ、リロード中、武器チェンジ中をわかりやすくする」

20.弾切れ、リロード中、武器チェンジ中をわかりやすくする

大きく分けて下記の三つをまとめて実装します
* 弾切れ中に左クリックしたらカチカチ鳴って弾切れしているとわかる
* リロード中、HUDにその情報を表示する
* 武器チェンジ中、HUDにその情報を表示する

弾切れ中にカチカチ鳴らす

サウンドファイルは適当なものを用意してきます。実装は下記の通り

うーんイケてない。「おしっぱで射撃できていい」という仕様と「おしっぱでカチカチならすと音がうるさい」という問題とがバッティングしてしまっているため、わざわざInput.GetButtonDownで判定を取り直しています。きれいにできそうな気もするんですけどまあええかまずは完成させたろの精神でスルー!

リロード中のHUDを表示

これも適当な画像を作ります。この画像を、リロード中の待ち時間の間表示します。

これはシンプルですね。リロードが始まったら表示してWaitForSecondsが終わったら消す。ちなみにこの画像はCanvas内に設置しています。次の武器チェン表示も要領は同じ。

武器チェンジ中のHUDを表示

こちらも適当な画像を用意。

おんなじですね。今回はこれで終わり!

次回はコチラ

公式チュートリアルSurvival Shooter WITH PK Chapter.21「敵の強さ、登場数、キャラクターの成長をデザインする」

前回はコチラ

Unity公式チュートリアルSurvival Shooter WITH PK Chapter.19「照準を表示する」

Unity公式チュートリアルSurvival Shooter WITH PK Chapter.19「照準を表示する」

19.照準を表示する

射撃がどこに飛んでいくかの目安となる照準(レティクル)を表示します。

画像を用意する


今回は32*32pixelで画像を書きました。これをCanvas上に設置し、マウスカーソルの位置を追うようにします。

Reticleクラスの実装

Reticleクラスを作成し中身を実装していきます。

超シンプルですが、ほぼ意図通りの挙動です。

バグ

射撃は、GunBarrelEndオブジェクトの正面に向かって真っすぐ飛んでいく実装になっています。
ただ、射撃の始点であるGunBarrelEndオブジェクトがPlayerの正中線よりやや右に設置されているため、レティクルの位置と実際に射撃が飛んでいく位置がずれてしまっています。
GunBarrelEndオブジェクトの位置を調整してみようと試行錯誤したのですがうまくいかず。このバグは仕様にしようそうしよう。

次回はコチラ

Unity公式チュートリアルSurvival Shooter WITH PK Chapter.20「弾切れ、リロード中、武器チェンジ中をわかりやすくする」

前回はコチラ

Unity公式チュートリアルSurvival Shooter WITH PK Chapter.18「カメラシェイク」

Unity公式チュートリアルSurvival Shooter WITH PK Chapter.18「カメラシェイク」

18.カメラシェイク

カメラシェイクとは、カメラ=画面が小刻みにぶるっと震える演出のことです。ダメージを与えた、受けた、壁に激しくぶつかったなど視点が揺れるときの演出として使います。今回はダメージを与えた時に画面が揺れるようにしてみましょう。かなり臨場感が増しました!

CameraShakeクラスの実装

新しくCameraShakeクラスを作成し、MainCameraにアタッチします。
ShakeTimeの値が正の間カメラが揺れ続け、Update内でShakeTimeの値を減らしています。負の値になると揺れが止まります。
PlayerShootingクラスのShootメソッド内で、ダメージを与えるタイミングでShakeTimeに揺らしたい秒数を入れることでカメラシェイクを実行しています。

public class CameraShake : MonoBehaviour {

public float ShakeTime { get; set; }

private void Start()
{
ShakeTime = 0.0f;
}

private void Update()
{
if (ShakeTime > 0.0f)
{
ShakeTime -= Time.deltaTime;
ShakeCamera();
}
else if(ShakeTime <= 0.0f)
{
ShakeTime = 0.0f;
}
}

public void ShakeCamera()
{
//カメラの揺らし幅
float x = Random.Range(-0.1f, 0.1f);
float y = Random.Range(-0.1f, 0.1f);

//カメラを揺らす
transform.position += new Vector3(x, y, 0);
}
}

次回はコチラ(執筆中)

前回はコチラ

Unity公式チュートリアルSurvival Shooter WITH PK Chapter.17.5「リファクタリング」

Unity公式チュートリアルSurvival Shooter WITH PK Chapter.17.5「リファクタリング」

17.5 リファクタリング

幻の第17回でコードを引っ掻き回した結果、PlayerShootingクラスが鬼のように見づらくなりました。今回は、リロードと武器チェンジの処理を別クラスに引っぺがし、射撃処理自体も関数化することで可読性を高めるリファクタリングを行います。どちらかというと、「こうなりました」という報告。

PlayerReloadクラス

今回Interfaceを練習がてら使ってみました。ただ、武器種ごとにリロードを実装するつもりだったのが結果的にReload関係のクラスは1つで済んだので、Interfaceの用途としては正しくありません。

Interfaceの説明については、こちらの説明が簡潔で非常に理解しやすかったです。
https://qiita.com/Akira_Kido_N/items/7cd18944173cd4cd7229

イメージをつかんだらこちらを読んでより本質的な理解に進むとよいかと。
https://niconare.nicovideo.jp/watch/kn3404

PlayerChangeWeaponクラス

switchの中をもっと共通化できないか30秒くらい悩んでできなさそうだったのであきらめました。

PlayerShootingクラス

全部張ると長くなるので、UpdateとShootメソッドだけ。特にShootメソッドの可読性が上がってます。

リファクタリングはうまくはまるとパズルを解いたような快感がありますね。漫画やゲームの整理が昔から好きだったのでその楽しさにも似てるかも。

次回はコチラ

Unity公式チュートリアルSurvival Shooter WITH PK Chapter.18「カメラシェイク」

前回はコチラ

Unity公式チュートリアルSurvival Shooter WITH PK Chapter.16「調整:攻撃中の移動速度を遅くする」

Unity公式チュートリアルSurvival Shooter WITH PK Chapter.17「調整:ノックバックを実装する」

17.調整:ノックバックを実装する

アクションゲームには欠かせないといってもいいノックバック演出。攻撃を当てた瞬間に、敵やプレイヤーの動きが止まってからリアクションが始まるというもの。

実装に当たって改めてノックバックについて調べてみると、様々なタイプがあるようです。ゲーム内の時間を丸ごと止めるもの、敵だけ、プレイヤーだけ止めるものなどなど。どのようなノックバックがあるかについては、下記の動画が大変参考になりました。

ゲーム開発でのヒットストップ調査

なんでもチャージショットで決めてしまうサムスが強すぎる【スマブラWiiU】

格闘でなく射撃であることを考慮すると「敵だけを止める」タイプのヒットストップが適しているかと思いました。以下、ヒットストップについての考え余談。

ヒットストップとはなんぞ

せっかくのアクションゲームだしヒットストップとか入れてみるか(開発延長)
剣とか格闘のゲームでは欠かせない演出だけど、銃とかシューティングではあんまり見ない気がする?サムスのチャージショットくらいしか例が浮かばない

射撃攻撃とヒットストップについて
仮説1:ヒットストップとは「吹っ飛ばし」の再現である
なので、ライフルとかサブマシンガン、レーザーみたいな貫通の攻撃とはあまり相性が良くない
逆に射撃であっても、ミサイルとか波動拳とかかめはめ波みたいな、衝撃の攻撃とは相性が良い

仮説2:ヒットストップとは「抵抗」の再現である
サンドバックを蹴れば、かならずサンドバックからの跳ね返りが存在し、無抵抗で振り抜くことはできない
その抵抗の感覚を再現するのがヒットストップであるため、自分の体から離れてしまった攻撃からは抵抗を受けないため、射撃とは相性が良くない

ここまで書いてて思ったけど、要するに現実世界に存在する「作用反作用」のフィードバックをいかにしてプレイヤーに与えるか、という問いに対する1つの答えってことかな
逆に言えば、ヒットストップを設けることで、射撃攻撃であっても「吹っ飛ばし」や「抵抗」のような作用反作用のフィードバックをプレイヤーに与えられる、ということだろうか

あとカメラシェイクか
こっちは実装したことあるからすぐいけるはず
ひとくちにヒットストップといってもさまざまなパターンがある模様
それらの挙動を比較してくれているこの動画がかなり参考になる。まずはこれを見て方向性を決めよう

やっぱり格闘と射撃とでは、適切なヒットストップの種類異なってくる気がするなぁ
射撃は自分に反作用のフィードバックがないわけで、自分が止まるタイプのヒットストップはおかしいよなあ
撃つ瞬間に自分だけ硬直⇒当たった時に相手だけ硬直して吹っ飛ぶ なら自然かな?

サムス:撃った瞬間反動でちょっと後ろに下がってる。ヒットストップというよりその反動で重量感を出しているもよう
ベヨネッタ:当たった瞬間その場で硬直してから吹っ飛んでる。硬直中は完全に動きが止まるわけじゃなくて、やられモーションのままぶるぶるしてる?それともエフェクトでそうみえるだけ?

こっちで見ると、食らったほうはその場で上下に細かく揺れたり震えたりしてるのがわかる
撃ったほうはストップしてるというか反動で後ろに下がるor硬直してるだけだな

ていうか格闘でも、攻撃したほうにはヒットストップ入れてないな
不利になっちゃうから当たり前か

ヌルっと止まると気持ちよくない、パキッとその場で止まって欲しいのでWaitForSecondsをつかうか。

WaitForSecondsの間に、別の変数やオブジェクトを格納してしまいNullReferenceエラー
LineRendererの終点
 WaitForSeconds後にLineの終点を更新していたため、更新される前にLineが描画されていた

ノックバックの時に操作するNavmeshAgent
 WaitForSeconds中に壁など敵以外のオブジェクトを打つと、shootHitの対象がエネミーからそのオブジェクトになってしまい、NavMeshAgentを見つけられるNullエラー

実装したけど削除しました!!!

一度実装してみたけど、思ったよりも爽快感に寄与せずゲームプレイがダラけただけだったので削除しました!
攻撃が当たった瞬間=ノックバック処理の実行直前に、NavMeshのVelocityを0にするStopMotionメソッドを事項してます。

がんばって作ったけど削除しました!!!
あと、これを実装するときにPlayerShootingクラスが超でぶになって見づらかったので、リファクタリングを一緒にしてます。これについては次回まとめます。

次回はコチラ

Unity公式チュートリアルSurvival Shooter WITH PK Chapter.17.5「リファクタリング」

前回はコチラ

Unity公式チュートリアルSurvival Shooter WITH PK Chapter.16「調整:攻撃中の移動速度を遅くする」

Unity公式チュートリアルSurvival Shooter WITH PK Chapter.16「調整:攻撃中の移動速度を遅くする」

16.調整:攻撃中の移動速度を遅くする

前回までで、主だった昨日の実装は一段落つきました。ここからは実際に遊んでみてのフィードバックをもとに、細かい部分の実装をしていきます。
気になったのは、逃げながら攻撃していればほぼ追いつめられることが無い点でした。敵の移動速度>プレイヤーの速度となるよう調整するのが一案ですが、例えばシールド象の移動速度を速くすると少々オーバーパワーのようです。そこで、「攻撃中だけプレイヤーの移動速度が遅くなる」ようにします。

PlayerMovementクラスにメソッドを追加

移動速度を遅くするメソッドと、遅くなった移動速度を回復させるメソッドを追記します。

このメソッドの実行は、PlayerShootingクラスから行います。

PlayerShootingクラスから実行

まずは遅くする処理。Shootingメソッドの中で実行します。
また、PlayerMovementの取得は、PublicでInspectorより行います。

次に移動速度を回復させる処理。こちらはUpdateメソッドから。

実装確認

撃ったら移動速度が遅くなる⇒チョットしたら戻る の挙動ができていればOK!

第17回がお蔵入りしたので次回はコチラ

※第17回ではノックバックの実装を行いましたが、イマイチだったので削除してます。それでも読みたい物好きはコチラ

前回はコチラ

Unity公式チュートリアルSurvival Shooter WITH PK Chapter.15「特殊な敵を実装する」