Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

[SOLVED]For Loop Causes Double Bullets

Discussion in 'Scripting' started by Skitto, Jun 19, 2017.

  1. Skitto

    Skitto

    Joined:
    Jun 3, 2017
    Posts:
    19
    Hello, I've been creating a game and I decided to recreate my weapon scripts to use a modular script able to be modified from the inspector that supports things such as burst fire and shotguns.

    However, I've hit a problem with the script. The code seems to double the amount of bullets that I specify in the inspector, when I've specified 1 in burstAmount, and only 1 value in each array.

    Below is my script:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class ProjectileFire : MonoBehaviour {
    5.  
    6.     //public Rigidbody projectile;
    7.     //public float speed = 5000;
    8.     public float fireRate = 10;
    9.     public float inaccuracy = 10f;
    10.     public Vector3 offset = new Vector3(0, 0, 1);
    11.     private float lastfired;
    12.     public ParticleSystem fireParticles;
    13.     public ParticleSystem fireParticles2;
    14.     public Light fireLight;
    15.     public Animator anim;
    16.     public int weaponid;
    17.     AudioSource audio;
    18.  
    19.     public int burstAmount;
    20.     public float[] speed;
    21.     public Rigidbody[] projectile;
    22.     public float[] delay;
    23.  
    24.     float randomNumberX;
    25.     float randomNumberZ;
    26.  
    27.     Vector3 direction;
    28.     Vector3 localOffset;
    29.     Vector3 offsetPos;
    30.  
    31.     GameObject player;
    32.     HealthControl healthControl;
    33.  
    34.         void Start ()
    35.     {
    36.         fireLight.enabled = false;
    37.  
    38.         audio = gameObject.GetComponent<AudioSource>();
    39.         GameObject player = GameObject.FindGameObjectWithTag("Player");
    40.         healthControl = player.GetComponent<HealthControl>();
    41.     }
    42.  
    43.     // Update is called once per frame
    44.     void Update()
    45.     {
    46.         if (healthControl != null)
    47.         {
    48.             if (healthControl.fireOff == true)
    49.             {
    50.                 enabled = false;
    51.             }
    52.         }
    53.    
    54.  
    55.         if (Input.GetButton("Fire1")) {
    56.  
    57.                 if (Time.time - lastfired > 1 / fireRate)
    58.                 {
    59.                 for (int i = 0; i < burstAmount; i++)
    60.                     {
    61.                     StartCoroutine(Fire(i));
    62.                     }
    63.                 }
    64.         }
    65.     }
    66.     IEnumerator Fire(int i)
    67.     {
    68.         yield return new WaitForSeconds(delay[i]);
    69.  
    70.     lastfired = Time.time;
    71.  
    72.     fireParticles.Play();
    73.     fireParticles2.Play();
    74.  
    75.     randomNumberX = Random.Range(-inaccuracy, inaccuracy);
    76.     randomNumberZ = Random.Range(-inaccuracy, inaccuracy);
    77.  
    78.     localOffset = transform.rotation * offset;
    79.     offsetPos = transform.position + localOffset;
    80.  
    81.     anim.SetTrigger("HasAttacked");
    82.  
    83.     audio.pitch = (Random.Range(0.6f, .8f));
    84.     audio.Play();
    85.  
    86.     Rigidbody instantiatedProjectile = Instantiate(projectile[i], offsetPos, transform.rotation) as Rigidbody;
    87.  
    88.     instantiatedProjectile.transform.Rotate(0, randomNumberX, 0);
    89.     instantiatedProjectile.AddForce(instantiatedProjectile.transform.forward * speed[i]);
    90.  
    91.     StartCoroutine(Timer());
    92. }
    93.  
    94.  
    95.     IEnumerator Timer() {
    96.  
    97.         fireLight.enabled = true;
    98.         yield return new WaitForSeconds (0.04f);
    99.         fireLight.enabled = false;
    100.  
    101.     }
    102.  
    103. }

    Here is a picture of what I have entered in the inspector:




    And here is a picture of the problem:
     
  2. Rick-Gamez

    Rick-Gamez

    Joined:
    Mar 23, 2015
    Posts:
    218
    You seem to maybe be starting the coroutine more than once. FYI the same coroutine can be started multiple times, maybe try a bool or the StopAllCoroutines() / StopCoroutine method.

    or try placing the for loop inside the IEnumerator method
     
    Last edited: Jun 19, 2017
  3. Skitto

    Skitto

    Joined:
    Jun 3, 2017
    Posts:
    19
    I do want the coroutine to activate more than once (as it is used to create the delay between the bullets), but only the amount of times specified by the burstAmount integer. Is the code in the for loop wrong? I could not figure out if there was something wrong with it.

    I don't think it's just adding 1 to the value either. At burstAmount 0, it will not fire anything, and at burstAmount 3 (with 3 values in each array as well) it will fire 6 bullets
     
    Last edited: Jun 19, 2017
  4. Skitto

    Skitto

    Joined:
    Jun 3, 2017
    Posts:
    19
    Nevermind, I solved it myself. I moved the fire rate time reset from the coroutine to the update, and it fixed itself.