前回までで弾を発射することができるようになりました。しかし、このままだと残弾数が分からないので不便ですよね。そこで今回は
- 残弾数を表示するゲージ
- 弾の供給までの時間を表すゲージ
のUIとスクリプトを作っていきましょう。
ちなみに、この段階で弾の補給方法をどうするか少し悩んだのですが、「一定時間が経つと自動的に全回復」させることにしました。ついでにこの変更もスクリプトに盛り込んでいきます。
キャンバスの作成
さて、まずUIを表示するにはキャンバス(Canvas)を作る必要があります。ヒエラルキーを右クリックして、「UI」→「キャンバス」を選択してください。そうしたら「キャンバススケーラ」コンポーネントの設定を下の図のように変更してください。
これで画面サイズが変わっても自動的にUIのサイズを調整してくれるようになります。
ゲージのUIの作成(+α)
ではゲージのUIを作っていきます。2種類のゲージに加えて、ついでにスコア表示も作ってしまいましょう。UIの画面上の配置と、ヒエラルキー上の階層はそれぞれ下の図の通りです。
弾薬ゲージ
まずは黄色の弾薬ゲージを作ります。ゲージは背景と、横方向に伸び縮みするゲージ本体で構成されます。
最初に適当な大きさのImage(「UI」→「画像」)を作り、下の画像のように設定します。
次にゲージ本体用のImageを作り、先ほど作ったゲージ背景の子に設定したら下の画像のように設定します。
こちらのほうはピボットの設定を忘れないようにしてください(ゲージの伸び縮みがおかしくなってしまいます)。
あとはゲージの横に残弾数を表示するためのテキストを作ってください。
供給ゲージ
弾薬ゲージと全く同様の手順でゲージを作ってください(※こちらはテキストは不要です)。
スコア表示用テキスト
新しくテキストを作って配置してください。なおここでは「SCORE:」というラベル部分とスコアの数値部分を別々に作っていますので注意。
FirstPersonGunControllerの変更
そうしたら前回作ったFirstPersonGunControllerを変更して、このスクリプトからゲージを操作するようにします。スクリプトを全部載せると長いし変更点が分かりづらいので適当に省略しておきますね。
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class FirstPersonGunController : MonoBehaviour { public enum ShootMode { AUTO, SEMIAUTO } public bool shootEnabled = true; [SerializeField] ShootMode shootMode = ShootMode.AUTO; [SerializeField] int maxAmmo = 100; [SerializeField] int maxSupplyValue = 100; [SerializeField] int damage = 1; [SerializeField] float shootInterval = 0.1f; [SerializeField] float shootRange = 50; [SerializeField] float supplyInterval = 0.1f; [SerializeField] Vector3 muzzleFlashScale; [SerializeField] GameObject muzzleFlashPrefab; [SerializeField] GameObject hitEffectPrefab; [SerializeField] Image ammoGauge; [SerializeField] Text ammoText; [SerializeField] Image supplyGauge; bool shooting = false; bool supplying = false; int ammo = 0; int supplyValue = 0; GameObject muzzleFlash; GameObject hitEffect; public int Ammo { set { ammo = Mathf.Clamp(value, 0, maxAmmo); //UIの表示を操作 //テキスト ammoText.text = ammo.ToString("D3"); //ゲージ float scaleX = (float)ammo / maxAmmo; ammoGauge.rectTransform.localScale = new Vector3(scaleX, 1, 1); } get { return ammo; } } public int SupplyValue { set { supplyValue = Mathf.Clamp(value, 0, maxSupplyValue); if(SupplyValue >= maxSupplyValue) { Ammo = maxAmmo; supplyValue = 0; } float scaleX = (float)supplyValue / maxSupplyValue; supplyGauge.rectTransform.localScale = new Vector3(scaleX, 1, 1); } get { return supplyValue; } } void Start() { InitGun(); } void Update() { if (shootEnabled & ammo > 0 & GetInput()) { StartCoroutine(ShootTimer()); } if (shootEnabled) { StartCoroutine(SupplyTimer()); } } public void InitGun() { Ammo = maxAmmo; SupplyValue = 0; } //--中略-- IEnumerator SupplyTimer() { if(!supplying) { supplying = true; SupplyValue++; yield return new WaitForSeconds(supplyInterval); supplying = false; } } }
主な変更点はプロパティのところにゲージを操作する処理を追加した点と、弾の回復値(=最大まで溜まると弾が全回復する値)を一定間隔で増やすコルーチンを追加した点ですね。難しいことはやっていないのでスクリプトを眺めてもらえば何をやっているかが何となく分かると思います。
できたらGunControllerオブジェクトのインスペクタを開いて、先ほど作ったゲージやテキストを設定してください。
下の動画のようにゲージが動いたらOKです。