Unityで銃に弾を装填する機能を作成してみる

今回までで銃を撃つ、持っている弾の数を減らすという事は出来ていました。

銃を撃つ機能は

Unityでバイオハザード風ガンシューティングの機能を作ってみる
Unityでバイオハザード風のガンシューティングの機能を作成していきます。今回は銃を構えそこからレーザーポインタを表示するようにし敵に当たっている時に攻撃ボタンを押すと敵にダメージを与えます。

を参照してください。

弾を減らしてUIで表示する機能は

UnityのUIで銃の残り弾数の表示をする
Unityでガンシューティング機能を搭載している時等にUIで銃の残り弾数の表示をしてわかりやすくします

を参照してください。

しかし銃に弾を装填する機能までは作成していなかったので、今回作成していきます。

スポンサーリンク

銃に弾を装填する時に使うアニメーションの用意

弾の装填は銃のマガジン(弾が入っている所)を取り出し、新しいマガジンをはめこむというアニメーションを用意し、アニメーションが終わったら銃に装填出来る弾の数だけ装填します。

マガジンごと変更しているので残っている弾もなくなるはずという突っ込みはなしでお願いします・・・・(^_^;)

銃はマガジンを変更出来る物に限定しております。

マガジンを変更するアニメーションを用意してください。
マグナムとかマシンガンとかはまた別のアニメーションが必要になると思います。

ご自分でアニメーションを作成する方は

blender2.76を使ってUnityで使うアニメーションを作成する
Unityで使用するキャラクター用のアニメーションをBlenderを使って作成していきます。作成方法を学べば自分のゲームに自前のアニメーションを使うことが出来ます。

を参考にしてください。

チャージ1

弾を装填するアニメーションは上のような感じになります。

遷移のアニメーションを切り取ったので本来のアニメーションとは違いますが、
本来は銃を構えた状態からマガジンをはめこむまでのアニメーションです。

主人公キャラのアニメーターコントローラーの作成

それでは主人公キャラクターのアニメーターコントローラーに状態と遷移を作成していきましょう。

アニメーションパラメータにChargeBulletをBoolで作成します。
このChargeBulletがOnになった時に弾を装填するアニメーションへと遷移させます。

チャージ2

上のようにCharge状態を作り、弾を装填するアニメーションクリップを設定します。

Chargeには新しくBehaviourを作成し名前をEndChargeとし、以下のスクリプトを記述します。

ChargeからWaitShotへと遷移したらアニメーションパラメータのChargeBulletをfalseにします。

WaitShot(銃を構えている状態)からChargeに右クリック→Make Transitionし遷移を繋げます。

チャージ3

Has Exit Timeのチェックを外し、条件がOnになったらすぐに遷移するようにします。
条件はChargeBulletがtrueになった時です。

チャージ4

Charge→WaitShotへと遷移を繋げ、Has Exit Timeのチェックを入れ、条件には何も入れません。
Has Exit Timeにチェックが入っているのでアニメーションが終了したら自動で遷移します。

WaitShotは立っている状態から銃を構える状態へ変わるアニメーションで、今回の場合は弾を装填した後に構え終わっている状態に遷移させたいので、WaitShotを左にスライドし、銃を構え終わる前のアニメーションを再生させないようにします。

これでキャラクターのアニメーターコントローラの設定が終わりました。

キャラクターの動きに合わせて銃のマガジンを動かすアニメーションの作成

次はキャラクターのアニメーションに合わせて銃のマガジンを取り出し、はめ込むアニメーションを作成していきます。

最初にお断りさせて頂きますが・・・、マガジンのアニメーションに関してはかなり雑な作りになっていると思います。
もっとちゃんと作りたい方には先に謝っておきます。(-.-)

では弾の装填をするアニメーションに合わせて銃のマガジンの移動を合わせていきます。
まずは弾を装填を開始する位置を調べる為にキャラクターを選択しAnimationタブを表示します。

チャージ5

上のようにAnimationタブを表示したら、画像のrig | Bullet (Read – Only)となっている個所をクリックし弾を装填するアニメーションを選択します。
rig | Bullet(Read – Only)の部分はわたくしの場合そういう名前になっているだけで、他の表示がされているはずです。

チャージ6

ここで、Animationの再生位置(時間が表示されている部分)をマウスドラッグして移動するとSceneタブのキャラクターがそのアニメーションを再生するので、手がマガジンをはめこみ始める場所を見つけます。
(一旦手が下がり、銃に向かって上がっていく所を探します)

チャージ7

Sceneタブだと上のような位置が0:10当たりになる事がわかりました。
またはめ込みが終わる時間(キャラクターの弾の装填アニメーションの再生終わり時間)が1:06秒です。

マガジンをはめこみ始める時間がわかったので、銃のマガジンのアニメーションを作成します。
銃のアニメーションに関しては

銃を撃った後の銃のアニメーションをUnityで作成する
Unityのゲームで使用している銃で弾を撃った時に銃のトリガーのアニメーションを作成していきます。

を参考にしてください。

銃のアニメーターコントローラーを選択し、Trigger型のChargeというアニメーションパラメータを作成します。

チャージ8

銃のマガジンの移動状態ChargeBulletを作成します。

チャージ9

GunIdle→ChargeBulletは上のように設定します。

チャージ10

ChargeBullet→GunIdleは上のようにします。

ではChargeBulletに設定する銃のアニメーションを作成していきます。

チャージ11

キャラクターが装備している銃を選択し、Animationタブを表示します。

チャージ12

上のCreate New Clipを選択しChargeBulletという名前を付けます(画像ではすでに作られていますが)。
Add PropertyをクリックしMagazineのPositionを追加します。

チャージ13

MagazineのPositionをシーン上で確認しながら位置を記憶させます。
上の画像のように0:00、0:10、1:06の位置にキーフレームを作成します。

0:10秒はキャラクターのアニメーションでマガジンをはめこみ始める時間で、1:06がはめ込み終わる時間です。

チャージ14

上が0:00秒の時のマガジンの位置です。
マガジンを取り外して移動させる為に遠い場所に設定します。

GunIdle→ChargeBulletへと遷移するので、銃にはめ込まれているマガジンからここで設定した位置に遷移していきます。

チャージ15

0:10秒マガジンをはめこみ始める位置なのでマガジンの位置を手の当たりに持っていきます。

Unityの実行ボタンを押してすぐに一時停止しコマ送りで位置を調整するといいかもしれません。
(他にもっといい方法があるかも?)

チャージ16

1:06の時はマガジンをはめこみ終わった時なので、本来の位置に合わせます。

リアルな銃のアニメーションを求めている方にはごめんなさい

記事の最初の方でマガジンのアニメーションに関してはかなり雑な作りになっていると思います。
と書きましたが、その理由は

銃のアニメーションでマガジンを移動させていて、GunIdle→ChargeBulletと遷移させる時にマガジンを外していますが、ChangeBullet→GunIdleと遷移が戻ってくるとマガジンが元の位置に戻ってきてしまいます。

つまり捨てるマガジンとはめこむマガジンを別のアニメーションには出来ていません。

マガジンに弾を詰め込みまた戻すというアニメーションであればこれでいいんですが、
今回の場合は捨てるのとはめこむマガジンを別に取り扱いたい所を一緒のマガジンで表現しています。

なのでリアルな感じではありません。

リアルな感じで作るならばマガジン自体をインスタンスにして、マガジンを取り外すアニメーションのタイミングで銃にはまっているマガジンを見えないようにし、同じ位置にマガジンのインスタンスを登場させ落とし、キャラクターがマガジンをはめこみ始める時になったらマガジンの別のインスタンスを登場させ銃にはめ込むという感じで作れるとは思います。

自分で書いててもわけわからなくなる・・・(^_^;)

武器のステータスを保持しているスクリプトWeaponStatusの修正

とりあえずこれでアニメーション関連は完成したので、次はスクリプトに処理を追加していきます。
弾を装填するには銃を構えている状態で左シフトキーまたはPS3コントローラーの×ボタンを押した時にする事にします。

PS3コントローラー等のゲームパッドを使いたい場合は

UnityでPS3コントローラー(ゲームパッド)に対応して動かしてみる
UnityのゲームでPS3コントローラー等のゲームパッドを使用してみます。パソコンのゲーム用コントローラーを持っていない人は便利かもしれません

を参考にしてください。

弾の数はキャラクターのステータススクリプトMyStatusに保持し、銃に弾を装填している数は武器のステータスWeaponStatusに保持するように変更します。

上がWeaponStatusスクリプトです。

limitChargeBulletは銃に装填出来る最大数で、chargeBulletが現在の装填数です。
銃のWeaponStatusのインスペクタでlimitChangeBulletとchargeBulletの値を設定してください。

MyStatusスクリプトにはprivate変数でNumberOfBulletという持っている弾の数を保持する変数が宣言されており、GetNumberOfBullet関数でその値を取得出来るようにしておきます。

銃に弾を装填させる為の処理を主人公操作スクリプトMoveに追加

それではキャラクター操作スクリプトMoveに処理を追加していきます。

Moveを作っていない方はご自分のキャラクター操作スクリプトに処理を追加してください。

Update関数内の処理分けしている部分だけなのと、他の処理が混じっている為非常に分かりづらいです。

以前は銃を撃った時にMyStatusの弾の数を減らしていましたが、銃に装填されている弾を減らすようにする為、銃を撃った時の処理を

status.SetNumberOfBullet(status.GetNumberOfBullet() – 1);
から
weaponStatus.SetChargeBullet(weaponStatus.GetChargeBullet() – 1);

に変更しました。

以前の記事で同じように作成していない方は特に気にしなくて大丈夫です。
(銃に装填している弾の数を減らす処理が記述されていればOKです)。

else if(Input.GetButtonDown(“Cross”) && endShot && prepareShot
&& !animatorState.IsName(“Charge”)
&& status.GetWeaponStatus().GetChargeBullet() < status.GetWeaponStatus().GetLimitChargeBullet()
&& status.GetNumberOfBullet() > 0) {

弾を装填する時のボタンを押した時は銃に装填されている弾の数が装填の最大数より少ない時でキャラクターが持っている弾の数が0より上の時です。

endShotは銃を打ち終わっているかで、prepareShotは銃を構え終わっているかの状態を確認する為の変数です。

弾を装填中状態の時は弾の装填数が最大値より下でキャラクターが持っている弾の数が0より上の時に弾の装填数を増やし、キャラクターが持っている弾の数を減らします。
ループの部分はwhileで書いた方がスッキリすると思います。

というよりループを使わず計算した方がいいと思います。(^_^;)
無限ループに陥るかも・・・・(-.-)

また状態がState.chargeBulletである時に他の動作をさせたくないので条件をいくつか加えています。

弾の数を表示していたUIに設定していたスクリプトCountBulletの修正

キャラクターが持っている弾の数で表示していたUIには銃に装填している弾の数を表示するように変更します。
UIに設定していたCountBulletスクリプトを変更します。

Update関数内でキャラクターステータスから今現在装備している武器を取得し銃に装填している弾の数であるGetChargeBullet関数を呼び出し、その値をUIに表示するようにします。

銃を撃った時の処理スクリプトShotの修正

また銃を撃った時の処理を実行するShotスクリプト内でレーザーポインタを表示している部分がありますが、レーザーポインタを表示する時の条件にState.waitshotという個所を

if(state == State.waitshot || state == State.chargeBullet) {

という条件に変え、弾を装填中もレーザーポインタの表示を更新出来るようにします。

これで銃に弾を装填する機能が完成しました。

弾の装填がうまくいくか確認してみましょう

それではUnityの実行ボタンを押して確認してみましょう。

チャージ17

上が実行結果です。

取りだしたマガジンが戻ってきてしまうのが確認出来ますね。
これが最初の方に言っていた雑な銃のアニメーションの事です。

注意するべき点として、アニメーターの状態を選択して、キャラクターの弾の装填アニメーションクリップのSpeedを変更する時は銃のマガジンの移動のアニメーションスピードも同じ値にする必要があります。

キャラクターの動作を秒数で調べ、それに合わせて銃のマガジンの移動をさせた為です。

今回の内容は他の色々な要素が合わさって出来ているので、非常に解りづらいです。

以前の記事の機能が出来ていないと今回の記事だけでは弾の装填の機能が完成出来ないので、
フラストレーションの溜まる方もいるかもしれませんが、ご了承くださいm(__)m

主人公操作スクリプトで弾の装填をさせるボタンを押した時にアニメーションパラメータの値を変更し、装填のアニメーションにさせ、装填中は移動や他の動作をさせないといった処理を加えていけば出来ると思います。

変にわたくしの作ったスクリプトShotの一部と同じにしない方がいいかもしれません(^_^;)