Unityで銃を撃つ #9 弾数に制限をかける

投稿者: | 2020-01-16


弾数に制限をかけて、残りの弾数が0になるとリロードできないようにします。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.UI;

public class GunScript : MonoBehaviour
{
    public ParticleSystem gunParticle;
    public GameObject gunLight;

    public Animator gunAnimator;

    public float rate = 0.075f;

    public GameObject bullet;
    public GameObject playerFace;
    public float power;

    public GameObject Zombie;
    public GameObject Ragdoll;
    List<GameObject> zombieList;

    public GameObject player;

    public static GameObject girlRagdoll;
    Camera playerCamera;

    const int magazineSize = 30;
    const int allBullets = 150;

    int currentMagazine = magazineSize; // 現在のマガジンの弾数
    int remaining; // 残りの弾数

    public Text bulletText; // 弾数を表示するテキスト

    // Start is called before the first frame update
    void Start()
    {
        remaining = allBullets - currentMagazine;

        zombieList = new List<GameObject>();
        StartCoroutine("GenarateZombie");
        playerCamera = playerFace.GetComponent<Camera>();

        girlRagdoll = Ragdoll;

        bulletText.text = currentMagazine + " / " + remaining; // 弾数を表示
    }

    // Update is called once per frame
    void Update()
    {

        // default状態で、マウス左クリックを押した時
        if (Input.GetMouseButtonDown(0) && currentMagazine > 0 && gunAnimator.GetCurrentAnimatorStateInfo(0).IsName("defualt")) // ママ
        {
            gunParticle.Play(); // パーティクルの再生
            gunAnimator.SetTrigger("Shoot");

            StartCoroutine("Shoot");

        }
        // MachineGin_shoot状態で、マウス左クリックを離した時
        else if (Input.GetMouseButtonUp(0) && gunAnimator.GetCurrentAnimatorStateInfo(0).IsName("MachineGin_shoot"))
        {

            gunParticle.Stop(); // パーティクルの停止
            gunAnimator.SetTrigger("Shoot");
            StopCoroutine("Shoot");

        }

        if (Input.GetKeyDown(KeyCode.T)) // Tキーを押した時
        {
            gunLight.SetActive(!gunLight.activeSelf); // ライトのオンオフ
        }

        if (Input.GetKeyDown(KeyCode.R) && currentMagazine < magazineSize && remaining > 0) 
        {
            if (gunParticle.isPlaying)
                gunParticle.Stop(); // パーティクルの停止

            gunAnimator.SetTrigger("DoReload"); // リロード状態に遷移させる

        }

        // リロードが終わったら
        
        if (gunAnimator.GetCurrentAnimatorStateInfo(0).IsName("MachineGun_reload") && gunAnimator.GetCurrentAnimatorStateInfo(0).normalizedTime >= 1)
        {
            gunAnimator.SetTrigger("DoReload"); // リロード状態からデフォルトに遷移させる

            if (currentMagazine + remaining > magazineSize) // 全残弾数がmagazineSizeより多いとき
            {

                remaining = currentMagazine + remaining - magazineSize; // 全残弾数からmagazineSizeを引く
                currentMagazine = magazineSize; // マガジンは満タン

            }
            else
            {// 全残弾数がmagazineSize以下のとき

                currentMagazine = currentMagazine + remaining; // 残っている弾を全てマガジンへ
                remaining = 0;

            }

            bulletText.text = currentMagazine + " / " + remaining; // 弾数を表示
        }

        


        if (Input.GetMouseButton(1) && gunAnimator.GetCurrentAnimatorStateInfo(1).normalizedTime >= 1 && (gunAnimator.GetCurrentAnimatorStateInfo(1).IsName("LookInAnimation2") || gunAnimator.GetCurrentAnimatorStateInfo(1).IsName("New State")))
        {
            //覗き込む

            gunAnimator.SetTrigger("LookIn");
            playerCamera.fieldOfView = 45f;
        }
        else if (!Input.GetMouseButton(1) && gunAnimator.GetCurrentAnimatorStateInfo(1).normalizedTime >= 1 && gunAnimator.GetCurrentAnimatorStateInfo(1).IsName("LookInAnimation"))
        {
            //覗き込むのをやめる

            gunAnimator.SetTrigger("LookIn");
            playerCamera.fieldOfView = 60f;
        }


    }

    private IEnumerator Shoot() // 弾を連射するコルーチン
    {
        while (currentMagazine > 0) // マガジンに弾があれば弾を発射し続ける
        {        
            Instantiate(bullet, playerFace.transform.position, playerFace.transform.rotation).GetComponent<Rigidbody>().AddForce(playerFace.transform.forward * power, ForceMode.Impulse);
            currentMagazine--; // 弾を一個減らす
            bulletText.text = currentMagazine + " / " + remaining; // 弾数を表示

            if (currentMagazine <= 0) // マガジンに弾がなくなった時
            {
                gunParticle.Stop(); // パーティクルの停止

                if (Input.GetMouseButton(0)) // 弾を発射していたら
                {
                    gunAnimator.SetTrigger("Shoot"); // 発射のアニメーションを止める
                }

                yield break; // コルーチンを終了
            }

            yield return new WaitForSeconds(rate);
        }
    }

    private IEnumerator GenarateZombie() // 1秒ごとにゾンビを生成するコルーチン
    {

        while (true)
        {
            zombieList.Add(Instantiate(Zombie,new Vector3(Random.Range(-88,88),0f,Random.Range(-88,88)),transform.rotation)); // ゾンビをランダムの位置に生成
            zombieList[zombieList.Count - 1].GetComponent<ZombieScript>().player = player;

            yield return new WaitForSeconds(1);
        }
        
    }
}

マガジンが満タンのときの弾数と、デフォルトの全弾数は定数にして、今のマガジンの弾数と、今の全弾数から今のマガジンの弾数を引いた残りの弾数の2つの変数を使っています。

マガジンが満タンのときと、残りの弾数が0のときはリロードできないように、リロードする条件を変えました。

if (Input.GetKeyDown(KeyCode.R) && currentMagazine < magazineSize && remaining > 0)

普通のFPSゲームと同様に、今のマガジンに弾が少し残っているときにリロードすると、今のマガジンの弾数と残りの弾数が合算されて、効率よくリロードされるようにしています。
そして、合算された全残弾数が、マガジンに満タンに入れたときの弾数よりも多い時とそれ以下のときで場合分けしています。

前者では、マガジンは満タンになるので、その分、全残弾数からマガジンサイズ分を引いて残りを表示します。

remaining = currentMagazine + remaining - magazineSize; // 全残弾数からmagazineSizeを引く
currentMagazine = magazineSize; // マガジンは満タン

後者では、全残弾数をすべてマガジンに入れて残りは0にします。

currentMagazine = currentMagazine + remaining; // 残っている弾を全てマガジンへ
remaining = 0;

コメントを残す

メールアドレスが公開されることはありません。