今回はUnityで銃の弾の残数を画面上に表示する機能を作ります。
今回の機能は以前から作成している機能に処理を追加していきますので、今までの機能作成の流れは以下の記事を参照してください。
ガンシューティングのゲーム等で銃を使っている場合、弾の数があるうちは発砲出来ます。
しかし画面上に弾の数が表示されていなければ、あと何発打てるのかわかりません。
そういった事がないようにUIを使って弾の数を表示します。
弾数が常に表示されていれば弾の使いどころがはっきりします。
弾の数が0になったら発砲の処理はせず、弾がない事を表す音声を鳴らします。
表示はスクリーンの上にUIとして作成するので常に同じ位置に表示されます。
弾を撃つ処理は
で作成しているので参考にしてください。
今回作成する弾の残り弾数の表示UIと弾の数の処理を追加すると
↑のような感じのものが作成出来ます。
ガンシューティングゲームが段々出来上がってきましたね。(^^)/
弾の弾数をUIで表示する機能の作成
それでは弾の弾数を表示する機能を作成していきます。
弾の情報を追加する
弾の弾数のUIを作成する前に、弾をどれだけ持っているかの情報が必要になりますので、キャラクターのステータスを管理しているMyStatusスクリプトに持っている弾の数という情報を加え、弾の数を返すメソッドを定義します。
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 | // ハンドガン用の弾の数 [SerializeField] private int numOfBulletsForHandGun = 30; // ショットガン用の弾の数 [SerializeField] private int numOfBulletsForShotGun = 10; // 弾の数を設定 public int SetNumberOfBullet(int num) { if (weaponStatus.GetWeaponType() == WeaponStatus.WeaponType.HandGun) { numOfBulletsForHandGun = num; } else if (weaponStatus.GetWeaponType() == WeaponStatus.WeaponType.ShotGun) { numOfBulletsForShotGun = num; } return num; } // 弾の数を取得 public int GetNumberOfBullet() { if (weaponStatus.GetWeaponType() == WeaponStatus.WeaponType.HandGun) { return numOfBulletsForHandGun; } else if (weaponStatus.GetWeaponType() == WeaponStatus.WeaponType.ShotGun) { return numOfBulletsForShotGun; } else { return 0; } } |
主人公が持っているハンドガン用、ショットガン用の弾の数の情報を持たせます。
弾の数のSetterとGetterを用意し、値の設定と取得を出来るようにしておきます。
銃を撃った時や弾を手に入れた時にSetNumberOfBulletメソッドを介して持っている弾の数を変更することになります。
次に武器のステータス情報を保持しているWeaponStatusスクリプトを修正します。
1 2 3 4 5 6 7 8 | public enum WeaponType { Sword, HandGun, ShotGun, Other } |
今まではGunとしていたものを選択しvisual studioの場合はCtrl+Rを押した後もう一回Ctrl+Rを押して背景が薄緑色の時にHandGunと入力します。
こうすることでWeaponType.Gunと記述していた他のスクリプト全てでWeaponType.HandGunと変更され保存されます。
新たにShotGunを増やしました。
弾の表示用UIの作成
それではUIを作っていきます。
まずはヒエラルキー上で右クリック→UI→CanvasでCanvasを1つ作成し名前をStatusUI、その子要素にUI→Panelを選択し名前をStatusPanel、その子要素にPanelを作成しBulletPanel、その子要素にUI→Imageを作成しBulletImage、UI→Textを作りKakeruText、UI→Textを作りNumTextとします。
↑のような階層で作成していきます。
CanvasのRenderModeはScreen Space Overlayを選択します。
これで画面の上にUIが表示されます。
StatusPanelはキャンバスの下の方にサイズを小さくして配置し、その子要素のBulletPanelはさらに小さくします。
↑のようなサイズにしました。
BulletImageの設定は
↑のようにBulletPanelの左側に表示します。
BulletImageに使用したアイコンはAssetStoreでテクスチャ&マテリアル→アイコン&UI→64 Flat Game IconsのInventory Bulletを使用します。
KakeruTextは×という表示をするだけです。
↑のようにBulletPanelの真ん中に表示します。
NumTextの設定は
↑のようにBulletPanelの右側に表示します。
弾の数を減らす処理をスクリプトに追加する
では銃を撃った時に弾の数を減らしていくスクリプトを作成します。
銃を撃つ処理を担当しているShotスクリプトに処理を記述します。
まずは銃を撃った時に弾があったかどうかで鳴らす効果音を変更する為のフィールド、弾の数を表示するテキストを設定するフィールドを宣言します。
1 2 3 4 5 6 7 8 9 10 11 | // 発砲音 [SerializeField] private AudioClip shotSE; // 弾がない時の音 [SerializeField] private AudioClip noBulletSE; // 弾の数を表示しているテキストUI [SerializeField] private Text bulletText; |
↑のように効果音と弾の数表示用Textを設定する事になります。
弾がない時の効果音はAssetStoreでオーディオ→効果音→武器→Futuristic weapons setのpower fist→idle_power_fist_1を使用しました。
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 | // 敵に弾が当たったかどうか public void JudgeShot() { // 弾がなければ弾がない時の効果音を鳴らしreturnで以降の処理をさせない if (myStatus.GetNumberOfBullet() <= 0) { PlaySE(noBulletSE); return; } // 銃の発砲の光を表示 AbleLight(); // 銃の発砲音を鳴らす PlaySE(shotSE); // 弾の数を減らし、戻り値をテキストに設定 bulletText.text = myStatus.SetNumberOfBullet(myStatus.GetNumberOfBullet() - 1).ToString(); Ray ray = new Ray(muzzle.position, muzzle.forward); RaycastHit hitPoint; distance = rayRange; if (Physics.Raycast(ray, out hitPoint, myStatus.GetWeaponStatus().GetWeaponRange(), LayerMask.GetMask("Field"))) { distance = Vector3.Distance(muzzle.position, hitPoint.point); } if (Physics.Raycast(ray, out hitPoint, myStatus.GetWeaponStatus().GetWeaponRange(), LayerMask.GetMask("EnemyHit"))) { if (distance > Vector3.Distance(muzzle.position, hitPoint.point)) { var enemyObj = hitPoint.collider.gameObject.transform.root; if (enemyObj.GetComponent<Enemy>().GetState() != Enemy.EnemyState.Dead) { var enemy = enemyObj.GetComponent<Enemy>(); enemy.TakeDamage(myStatus.GetWeaponStatus().GetShotPower(), hitPoint.point); } } } } |
弾がなければ弾がない時用の効果音を鳴らし、returnでそれ以降の処理を実行しないようにします。
弾があった場合は銃の発砲の光と発砲音を鳴らし、myStatus.SetNumberOfBulletで弾の数を減らしその戻り値をbulletTextに設定します。
次にPlaySEメソッドは今まで銃に設定されているAudioSourceに元々設定してある銃の発砲音を鳴らしていましたが、弾がない時は別のオーディオクリップを再生したいので、再生するオーディオクリップを受け取り、そのクリップを再生するように変更します。
1 2 3 4 5 6 | public void PlaySE(AudioClip clip) { audioSource.clip = clip; audioSource.Play(); } |
AudioSourceのクリップに引数で受け取ったクリップを設定し、その後再生させます。
弾を表示するテキストUIは銃に切り替えた時に変更したいので、InitializeGunメソッド内に処理を追加します。
1 2 3 4 5 6 7 8 9 10 | // 銃の情報を取得 public void InitializeGun(GameObject weapon) { raserPointer = weapon.GetComponentInChildren<LineRenderer>(); shotLight = weapon.GetComponentInChildren<Light>(); audioSource = weapon.GetComponentInChildren<AudioSource>(); muzzle = weapon.transform.Find("Muzzle"); bulletText.text = myStatus.GetNumberOfBullet().ToString(); } |
これで装備をハンドガンタイプやショットガンタイプに切り替えた時、弾の数が変更されるようになります。
終わりに
これで銃の弾の管理も出来るようになりました。
弾の数に制限があると銃の使いどころを考慮する必要があり、ゲーム性が非常に増しますね。(^^)/
弾を取得する機能を搭載する時もMyStatusスクリプトのSetNumberOfBulletにGetNumberOfBulletの戻り値に取得した弾の数を設定すれば簡単に出来そうですね。
今回の場合はハンドガンに切り替えた時にハンドガンの弾の数を設定していますが、装備を切り替える前はbulletTextのデフォルト値が表示されています。
銃以外の武器の場合は弾の数を表示するUI自体を消すか、もしくは持っている銃の種類全部の弾の数を最初から表示しておくなどそこら辺は色々やり方がありそうですね。
次回は敵キャラクターのHPを頭上に表示するUIを作成します。