2
\$\begingroup\$

I have this script and I need to fix one thing which is count correctly the number of bullets I have.

public GameObject ebullet;
public Transform Bullet_position, target;

public int ammo = 200;
public int ammo_Hold = 600;
public bool reload = false;
public bool readyToShoot;

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

    if (ammo == 0)
    {
        ammo_Hold = ammo_Hold - 200;
        ammo = 200;
    }

    if (reload == true && ammo_Hold >=0)
    {
        ammo_Hold = ammo_Hold - ammo;
        reload = false;
    }

    if (readyToShoot == true)
    {

        Quaternion rotation = Quaternion.LookRotation(target.position - transform.position);
        transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * 5.0f);

        GameObject bullets = Instantiate(ebullet) as GameObject;
        bullets.transform.position = Bullet_position.transform.position * 1;
        Rigidbody rb = bullets.GetComponent<Rigidbody>();
        rb.velocity = transform.forward * 100;
        Destroy(bullets, 2f);
        ammo--;

    }
    else
    {
        print("Don't Shoot");
    }

} // end update
\$\endgroup\$
  • \$\begingroup\$ I don't understand, what's the problem? This isn't a question that can be answered if we don't know what the problem is. \$\endgroup\$ – clabe45 Sep 24 '18 at 23:45
2
\$\begingroup\$

If I understand your code correctly, I believe you are using ammo as the ammo that has been loaded, and ammo_Hold as the ammo remaining in the player's inventory. So the player should be able to fire 200 rounds before they have to reload, and they can do this up to 4 times since they have 200 rounds + 600 in the inventory. Please correct me if I have this wrong. I made some slight modifications to your code below without overhauling how it was written.

First of all, you want a variable to keep track of the magazine size. In your case, it is 200. We will call this magazineSize. When the player reloads, you want to subtract the number of rounds that were used from ammo_Hold. As it is written, you are subtracting the number of unused rounds from the player's inventory. We can use (magazineSize - ammo) to figure out the number of rounds that were used. Also, add a check to avoid ammo_Hold from going negative.

if (reload == true && ammo_Hold >=0)
{
    if (ammo_Hold >= (magazineSize - ammo))
    {
        ammo = magazineSize;
        ammo_Hold = ammo_Hold - (magazineSize - ammo);
    }
    else
    {
        ammo = ammo + ammo_Hold;
        ammo_Hold = 0;
    }

    reload = false;
}

Also, when ammo reaches 0 I don't think you want to blindly load the player's gun with 200 rounds. You want to add as much to ammo as you can without going over how much you have remaining in ammo_Hold. Add a simple check to handle this.

if (ammo == 0)
{
    if (ammo_Hold < magazineSize)
    {
        ammo = ammo_Hold;
        ammo_Hold = 0;
    }
    else
    {
        ammo = magazineSize;
        ammo_Hold = ammo_Hold - magazineSize;
    }
}

Finally, you should add a check to see if you have any ammo available before firing.

if (readyToShoot == true && ammo > 0)

Complete Code:

public GameObject ebullet;
public Transform Bullet_position, target;

public int magazineSize = 200;
public int ammo = 200;
public int ammo_Hold = 600;
public bool reload = false;
public bool readyToShoot;

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

    if (ammo == 0)
    {
        if (ammo_Hold < magazineSize)
        {
            ammo = ammo_Hold;
            ammo_Hold = 0;
        }
        else
        {
            ammo = magazineSize;
            ammo_Hold = ammo_Hold - magazineSize;
        }
    }

    if (reload == true && ammo_Hold >=0)
    {
        if (ammo_Hold >= (magazineSize - ammo)) //Check if you have enough ammo to do a full reload.
        {
            ammo = magazineSize;
            ammo_Hold = ammo_Hold - (magazineSize - ammo);
        }
        else
        {
            ammo = ammo + ammo_Hold;
            ammo_Hold = 0;
        }

        reload = false;
    }

    if (readyToShoot == true && ammo > 0)
    {

        Quaternion rotation = Quaternion.LookRotation(target.position - transform.position);
        transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * 5.0f);

        GameObject bullets = Instantiate(ebullet) as GameObject;
        bullets.transform.position = Bullet_position.transform.position * 1;
        Rigidbody rb = bullets.GetComponent<Rigidbody>();
        rb.velocity = transform.forward * 100;
        Destroy(bullets, 2f);
        ammo--;

    }
    else
    {
        print("Don't Shoot");
    }

} // end update
\$\endgroup\$
  • 1
    \$\begingroup\$ Thank you so much for all this. You cleared many things to me. Just one thing I need you to look at it again please. In this part [ if (reload == true && ammo_Hold >=0) ] If I i reload, ammo value not change. example, ammo = 120 and i relaod it.It should be 200 but it keeps 120 !! I tried to solved....could you check it please. \$\endgroup\$ – Omer Sep 24 '18 at 21:40
  • \$\begingroup\$ Ah I see the problem. I left out the part where ammo is updated. I have updated my answer with modifications to that section of code. You'll want to check if you have enough bullets remaining in ammo_Hold to fully reload. \$\endgroup\$ – Alex Myers Sep 24 '18 at 22:20
1
\$\begingroup\$
if (ammo == 0)
{
    ammo_Hold = ammo_Hold - 200;
    ammo = 200;
}

If ammo_Hold is not a multiple of 200 it will break.

if (reload == true && ammo_Hold >=0)

Not really important and it comes to preference I think but reload is a boolean so basically you check true == true or false == true, so instead you can just type if (reload && ammo_Hold >=0).

if (readyToShoot == true)

Same thing. Also I don't where you set it to be true.

Another thing, you use Update instead of fixedUpdate, this means someone with a higher frameRate can shoot faster then someone with a lower frameRate.

About the question... It would be better to work with timing. It happens that the unity time example is also about shooting!

https://docs.unity3d.com/ScriptReference/Time-time.html

In case the docs ever break, here (part of) the code referenced from the link.

public class ExampleClass : MonoBehaviour {
    public GameObject projectile;
    public float fireRate = 0.5F;
    private float nextFire = 0.0F;
    void Update() {
        if (Input.GetButton("Fire1") && Time.time > nextFire) {
            nextFire = Time.time + fireRate;
            GameObject clone = Instantiate(projectile, transform.position, transform.rotation) as GameObject;
        }
    }
}

Now you are back to the bullet problem again. Before you shoot you can check if Ammo > 0. Within the shooting you can check if it reaches 0. If it does I would set a boolean reload_required to true. But I leave that up to you as an exercise. I hope it helps.

\$\endgroup\$
  • \$\begingroup\$ Good point. thank you for giving me option to add new things into my script. \$\endgroup\$ – Omer Sep 24 '18 at 21:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.