弾数を表示します。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.ToString();
}
// 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))
{
if (gunParticle.isPlaying)
gunParticle.Stop(); // パーティクルの停止
gunAnimator.SetTrigger("DoReload"); // リロード状態に遷移させる
}
// リロードが終わったら
if (gunAnimator.GetCurrentAnimatorStateInfo(0).IsName("MachineGun_reload") && gunAnimator.GetCurrentAnimatorStateInfo(0).normalizedTime >= 1)
{
gunAnimator.SetTrigger("DoReload"); // リロード状態からデフォルトに遷移させる
currentMagazine = magazineSize; // マガジンを一杯にする
bulletText.text = currentMagazine.ToString(); // 弾数を表示
}
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.ToString(); // 弾数を表示
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);
}
}
}
弾を発射するコルーチンの中でwhile文で銃弾の発射を繰り返しますが、現在のマガジンが0より大きいという条件を付けました。
弾を発射するたびに現在のマガジンの弾数を1つ減らして、弾数を画面に表示しています。
マガジンの弾が0になったらマズルフラッシュのエフェクトを停止して、「Shoot」パラメータをセットすることで、銃が振動するようなアニメーションを止めます。
この SetTrigger(“Shoot”) は弾を発射しているときに、マウスの左クリックを離したときにも使われますが、条件に GetCurrentAnimatorStateInfoメソッドを使って、弾を発射するステートにいるときだけ実行されるようにしているので、マウスの左クリックを押しながらリロードが終わった後に左クリックを離しても、再度「Shoot」パラメータがセットされることはありません。
リロードが終わったことを Animator.GetAnimatorTransitionInfo で知ろうと思ったのですがうまく動きませんでした。
https://docs.unity3d.com/ja/2017.4/ScriptReference/Animator.GetAnimatorTransitionInfo.html
リロード状態からデフォルトへの遷移はパラメータを使わずに、Has Exit Timeを使って時間が立つと自動で遷移するようにしていましたが、リロード状態にいる時に、アニメーションの再生が終わったらという条件がうまくいかなかったので、この遷移でも「DoReload」トリガーを使ってHas Exit Timeを使わずにスクリプトから遷移させるようにしました。
アニメーションが最後まで再生されたかどうかを知るには、GetCurrentAnimatorStateInfo(0).normalizedTimeを使っています。
if (gunAnimator.GetCurrentAnimatorStateInfo(0).IsName("MachineGun_reload") && gunAnimator.GetCurrentAnimatorStateInfo(0).normalizedTime >= 1)
{
gunAnimator.SetTrigger("DoReload"); // リロード状態からデフォルトに遷移させる
currentMagazine = magazineSize; // マガジンを一杯にする
bulletText.text = currentMagazine.ToString(); // 弾数を表示
}
次は全体の弾数に制限をかけて、それが0になるとリロードできないようにしてみます。