FPSを作ってみよう16-銃を撃った時の反動を付ける-

久しぶりのFPSを作ってみようの記事です。

と言っても、ブログのコメント欄に頂いた質問に返信した内容を編集しただけですが・・・・(^_^;)

今回やる事は、銃を撃った時の反動をスクリプトから作っていきます。

以前の記事ではキャラクターが銃を撃った後のアニメーションとして、銃の反動を表現していました。

もちろんこれでも実現出来ますが、スクリプトから反動の処理を行うと銃をハンドガンからマシンガンに変えた時などにもそのスクリプトですぐに表現出来るところです。

アニメーションで作成すると銃ごとに反動のアニメーションを細かく作成する事が出来ますが、手間がだいぶかかります。

スクリプトの場合はシンプルですが柔軟性があります。

スポンサーリンク

スクリプトで反動を表現する時に必要な事、不必要な事

不必要になる事

スクリプトから銃の反動を表現すると、Animatorに作っていた銃を撃った時のアニメーションの遷移を作成する必要がなくなります。

銃を撃った後の状態がいらなくなる

今まで作成していた銃を撃った時の遷移は↑の赤い四角の部分です。

ですが、反動の部分ではなく引き金を引く時の指の細かいアニメーションも設定している場合は残したままの方がいいと思います。

銃を構えているWaitShot状態から反動を加えたアニメーションを再生するShot状態へと遷移させて戻る部分なのでShot状態はいらなくなります。

それに伴って、銃を撃った時のスクリプトでアニメーションパラメータのShotを操作していた部分もいらなくなります。

この後作成する、カメラを動かす、設定したボーンを動かす場合は残す必要があります。

必要になる事

FPSをつくってみようカテゴリの記事では銃の反動をアニメーションで作成していました。

なのでスクリプトから反動を表現する事を念頭に置いていなかった為、MyCharaスクリプト(キャラクター操作スクリプト)とMain Cameraに設定したスクリプトで個別にダミーのCameraPositionを変更しています(現在は修正済み)。

両方でダミーカメラ位置を操作している為、反動がうまく適用できません。

スクリプトで反動の処理を作成する

スクリプトで反動の処理を作っていきたいと思います。

スクリプトから反動を表現するにはカメラだけを動かすか、キャラクターのボーンの角度を動かす事で、銃を撃った時の反動を表現します。

カメラだけを動かす、単にボーンをランダムに動かすやり方と、キャラクターの腰のボーンを一定角度まで回転させてから元に戻す方法の3通りの方法をやってみたいと思います。

カメラだけをランダムに動かす

まずはカメラだけをランダムに動かす方法です。

このやり方を行う場合はアニメーションパラメータのShotの処理を残しておく必要があります。

この方法はFPS視点のカメラの位置を動かす事で反動を表現しますが、キャラクター自体の体は動かしません。

カメラのダミー位置CameraPositionに反動スクリプトWaveCameraを作成し取り付けます。

CameraPositionに反動のスクリプトを取り付ける

銃を撃っている時はアニメーションパラメータのShotをオンにしているので、その間はランダム値を使ってCameraPositionのローカル位置を動かします。

Shotがオフになったら元に戻します。

アニメーションパラメータのShotを使って処理の判断をしている為、Shotを残すか時間計測で判断する必要があります。

WaveCameraに設定をして確認してみます。

WaveCameraの設定

↑のようにWaveには非常に小さい値を入れます。

カメラを動かした反動のサンプル

↑のような感じになりました。

特定のボーンをランダムに動かす

次は特定のボーンに取り付けて、そのボーンを小刻みに動かす方法です。

このスクリプトは動かしたいボーンに取り付けます。

スクリプトの内容はWaveCameraとほとんど同じです。

今回はEthanの右ひじと左ひじ(交互に見て♪)にスクリプトを設定し、動かして見たいと思います。

右ひじ、左ひじを反動で動かす

EthanRightForeArmの位置は、

EthanRightForeArmの位置

↑の辺りです。

このボーンをスクリプトから動かします。

WaveBoneの設定値は以下のようにします。

WaveBoneの設定値

それでは実行してみましょう。

WaveBoneを実行したサンプル

↑のようになりました。

右ひじと左ひじは個別に動かしているので、同じ動きにしたい場合はスクリプトを書き換える必要があります。

スクリプトをキャラクター自身等に取り付け、右ひじと左ひじのTransformをpublic等で宣言し、取得出来るようにします。

後はランダム値を作り、右ひじ、左ひじのそれぞれの位置をそのランダム値で動かすと同じ動きになります。

ボーンを特定の角度まで動かしてから元に戻す

最後に、胸のボーンを特定の角度まで動かしてから元に戻して反動を表現する方法です。

MyCharaスクリプトに処理を追加していきます。

まずはフィールド宣言です。

maxRecoilは反動で動かす角度を指定します。
recoilSpeedは上向きに移動するスピード、undoSpeedは元の角度に戻るスピードを指定します。

次に銃を撃つキーを押した時の処理に追加します。

銃を撃った時にrecoilFlagがオフ(反動処理をしていない)の時にrecoilFlagをオン、recoilUpをオン、defaultRotに現在のダミーカメラCameraPositionの角度を入れておきます。

recoilUpは反動で跳ね上がっている状態の時で、オフの時は元の位置に戻る状態の時です。

次に実際に反動処理を行う部分です。

角度の変更はLateUpdateメソッド内に記述します。

recoilFlagがオンの時は反動が起きている状態で、その後recoilUpの状態を見て銃が跳ね上がっている時か、元に戻っている時かを判断し、ダミーカメラの角度を変更しています。

跳ね上がっている時はダミーカメラの角度と元の角度が限度角度内であればダミーカメラの角度を限度角度まで変更します。

限界角度までいったら、recoilUpをfalseにし、ダミーカメラの角度を元の角度に戻していきます。

ダミーカメラの角度が元の角度に戻ったらrecoilFlagをfalseにして、反動処理の終了とします。

cPos.localRotationとdefaultRotを==で比較していますが、反動ではX軸の角度だけを変更しているのでMathf.Approximatelyを使ってそれぞれのX軸の角度を比較し、判定した方が正しい結果が得られるかもしれません。

それではMyCharaスクリプトの反動のパラメータを設定し確認してみましょう。

反動用のパラメータ設定

↑のような感じのパラメータを設定します。

↑のようになりました。

反動のパラメータによって動きが変わるので、反動が大きいバズーカ等はmaxRecoilを大きくすると良さそうですね。

動画で銃を撃った時に反動が起きていない時がありますね・・・、動画を作ったのは少し前の事なのでどうだったか忘れてしまいました・・・(^_^;)

今、確認してみたところ問題は出ていませんが、何かあれば処理に修正を入れるかもしれません(入れないかもしれません)。

スポンサーリンク

記事をシェアして頂ける方はこちら

フォローして頂くとやる気が出ます