12.射撃にリロードを設ける
必要なことは3つ
* 射撃可能回数に制限を設ける(1マガジンで撃てる数)
* ボタンを押すと射撃可能回数が最大まで回復する
* マガジンの数は無限。資源の管理はこのゲームの面白さに据えないので。
* オートリロードは設けない。俺のリロードは革命(レボリューション)なので。
* リロード中射撃できない時間を設ける。マグチェンジではとうてい味わえない緊張感と高揚を戦闘にもたらすので。
弾数制限&リロードの基本を実装
PlayerShooting.csをいじるよ。具体的にはこんな感じ
* 残弾数としてint変数currentAmmo、装填数としてint変数maxAmmoを用意
* Shoot()を実行するたびにcurrentAmmoを減らす
* Shoot()の実行条件にcurrentAmmoが0でないことを追加
* Rを押したらcurrentAmmoにmaxAmmoを代入するReload()メソッドを実行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
//残弾数と装填数 int currentAmmo; //Shoot()で減らす public int maxAmmo = 10; void Awake () { (略) //マガジンに弾を込める currentAmmo = maxAmmo; } void Update () { timer += Time.deltaTime; if(Input.GetButton ("Fire1") && timer >= timeBetweenBullets && Time.timeScale != 0) { //残弾数のチェック if(currentAmmo <= 0) { return; } else { Shoot(); } } (中略) if (Input.GetKeyDown(KeyCode.R)) { Reload(); } } void Shoot () { (略) //残弾数を減らす currentAmmo--; } void Reload() { currentAmmo = maxAmmo; } |
ミスった点として、Shoot()実行前の残弾数をチェックするタイミングがあります。
最初、
1 2 3 4 5 6 |
if(残弾数0以下なら){ return; }else if(左クリックされたら(略)){ Shoot() } |
という風に、最初に判定してreturnで抜けてしまったところ、残弾が0になった瞬間Update内のすべてのメソッドが効かなくなりました。
ifの一塊だけ抜けて、Update内の次の関数に行ってほしかったんですが、残弾数の判定⇒0なのでUpdateメソッド自体を抜ける⇒次フレームで再度Updateメソッド実行⇒…の無限ループしちゃいました。幸いすぐ気づいて直せました。
リロードタイムを設ける
リロードボタン(Rキー)を押してn秒後にReload()メソッドを実行するようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
//リロードタイム public float reloadTime = 3.0f; void Update () { (略) if (Input.GetKeyDown(KeyCode.R)) { Invoke("Reload", reloadTime); } (略) } |
これでリロード中は射撃ができないようになりました。リロードタイムがこんなにも息吹を……!!
[追記]嘘です。この実装だとリロード中も射撃できます。あとで直す。
残弾数のUI表示
3枚のスプライトを重ね、FillAmountを使って表現します。
実際に用意した画像ファイルは4枚、一番上の外枠と、内枠の区切りを示す一本の黒い線とで2枚に分けました。バランス調整や、別の武器の実装で装填数の異なるUIを作るとき、応用が利くようにしたかったためです。等間隔になるようなPosition設定がめんどいので、1枚で書いてもそんなに手間が変わらないかも。
HUDCanvas下にImageオブジェクトを4つ追加してそれぞれ画像ファイルを設置。
Projectビュー内の画像ファイルTextureTypeをSprite(2D and UI)にするのを忘れずに。
PlayerShootingスクリプトで制御する必要があるのは真ん中の黄色いスプライトのみです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
//残弾数UIのオブジェクトと残弾数自体のImageコンポーネント GameObject ammoFullObj; Image ammoFullImg; void Awake () { (略) //残弾数UIのオブジェクトとコンポーネントを取得 ammoFullObj = GameObject.Find("AmmoFullImg"); ammoFullImg = ammoFullObj.GetComponent<Image>(); } void Shoot () { (略) //残弾数UIを減らす //1でなく1.0fで書かないとちゃんと割り算の結果が小数で返らないっぽい ammoFullImg.fillAmount -= 1.0f/ maxAmmo; } void Reload() { (略) //残弾数UIを戻す ammoFullImg.fillAmount = 1.0f; } |
ついでに、武器変更機能を見越して、装備中の武器がわかるようなHUDも追加しました。
リロード中の表現
グラフィックでやろうと思ったんですが、AssetStoreに無料でいい感じのオーディオ素材があったのでそちらで実装してみます。
MentalDreams, Weapon Soldier Sounds Pack
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
public AudioClip fireClip; public AudioClip reloadClip; void Update () { (略) if (Input.GetKeyDown(KeyCode.R)) { //リロードSEへ差し替え&再生 gunAudio.clip = reloadClip; gunAudio.Play(); Invoke("Reload", reloadTime); } } void Shoot () { //射撃SEへ差し替え&再生 gunAudio.clip = fireClip; gunAudio.Play (); } |
リロードタイム3秒で丁度SEの長さとあってますが、今後のバランス調整を経てズレてきた場合は、SEの長さを調整する必要が出てきそうです。
これでリロード周りの実装は終わりです。次回はノックバックを実装しますよ~
それとタイトル名決めました。
SurvivalShooter Who In The Hell Punches or Kicks? -やさしい地獄へようこそ-
略してSurvivalShooter WITH PKです。どうぞよろしく。
次回はコチラ
Unity公式チュートリアルSurvival Shooter WITH PK Chapter.13「敵に射撃がヒットした時、ノックバックする」
前回はコチラ
「Unity公式チュートリアルSurvival Shooter WITH PK Chapter.12「射撃にリロードを設ける」」への2件のフィードバック