- Home /
 
Check timer time when changed it.
Hello. I have a question that i cant solve my self. I am making tower defence game and i added rapid fire upgrade that change time value in the time but its still the same speed because it does not check it when i buy that upgrade. How can i make that when i purchase it, it will check the timer after the upgrade is applied then it will start using the new time i hope you understand. I am using unity 5 beta pro. Here is the timer script:
 using UnityEngine;
 using System.Collections;
 
 public class TurretShooting : MonoBehaviour {
     
     public Rigidbody cannonball;
     public Transform cannonend;
     private float cannonballspeed = 1500f;
     public float firerate = 3.0f;
     
     public void Start () {
         InvokeRepeating("shootcannonball", 1, firerate);
     }
     void shootcannonball () {
         Rigidbody cannonballrig;
         cannonballrig = Instantiate (cannonball, cannonend.position, cannonend.rotation) as Rigidbody;
         cannonballrig.AddForce (-cannonend.forward * cannonballspeed);
     }
 }
 
 
               See that firerate in invokerepeating timer? yeah the upgrade change that value but it does not detect it and keeps using the old time. How can i make that it would check in this upgrade script:
using UnityEngine; using System.Collections; using UnityEngine.UI;
public class CannonRateOfFireUpgr : MonoBehaviour {
 private Databasestorage database;
 private int Cost = 15;
 public GameObject Cannon1;
 public GameObject Cannon2;
 // Use this for initialization
 public void increaserateoffire () {
 
     database = GameObject.Find ("Main Camera").GetComponent<Databasestorage> ();
     //Cannon3 = GameObject.Find ("Cylinder001").GetComponent<TurretShooting> ();
     //Cannon4 = GameObject.Find ("Cylinder001").GetComponent<TurretShooting> ();
     if (Cannon1.GetComponent<TurretShooting> ().firerate < 0.2f && Cannon2.GetComponent<TurretShooting> ().firerate < 0.2f) {
         transform.Find ("CannonRateOfFireText").GetComponent<Text> ().text = "Cannon Rate Of Fire\nMAX UPGRADED";
     } else {
         if (database.money > Cost) {
             
             database.money -= Cost;
             Cannon1.GetComponent<TurretShooting> ().firerate -= 0.1f;
             Cannon2.GetComponent<TurretShooting> ().firerate -= 0.1f;
             //Cannon3.GetComponent<TurretShooting>().firerate -= 0.1f;
             //Cannon4.GetComponent<TurretShooting>().firerate -= 0.1f;
             Cost += 12;
             transform.Find ("CannonRateOfFireText").GetComponent<Text> ().text = "Cannon Rate Of Fire\nCost " + Cost;
         }
     }
 }
 
               }
I tried adding the Start() in the button but it start a new timer and then its shooting 2 bullets at 1 time... that is bad. Soo how can i check it? sorry again if this is very confusing.
Answer by Reaper1121 · Mar 19, 2015 at 01:09 PM
Fixed. It was very easy when you gived me the idea. You dont need that much code. Here:
 using UnityEngine;
 using System.Collections;
 
 public class TurretShooting : MonoBehaviour {
     
     public Rigidbody cannonball;
     public Transform cannonend;
     private float cannonballspeed = 1500f;
     //public float firerate = 3.0f;
     public float firerate = 3.0f;
     public float fireratereset = 3.0f;
     
     void Update () {
 
         //InvokeRepeating("shootcannonball", 1, firerate);
         firerate -= Time.deltaTime;
 
         if (firerate <= 0) {
             shootcannonball();
             firerate += fireratereset;
         }
 
     }
     void shootcannonball () {
         Rigidbody cannonballrig;
         cannonballrig = Instantiate (cannonball, cannonend.position, cannonend.rotation) as Rigidbody;
         cannonballrig.AddForce (-cannonend.forward * cannonballspeed);
     }
 }
 
              One more note. I changed float on firerate and fireratereset to double to work no problem in my upgrades script.
Answer by fafase · Mar 19, 2015 at 09:38 AM
The issue here is that the Invoke method uses a copy of your firerate so changing firerate does not affect the value inside the method since it is bound to the old value.
I would go with my own coroutine to fix that:
 private float timer = 0f;
 private float fireRate = 3f;
 public float FireRate
 {
    get {return fireRate;}
    set{
       // Check that value is fine, not too big/small, not negative else...
      fireRate -= value;
      timer = fireRate; // This line is dependent of what you want to achieve
      // it would reset timer to the new value of firerate.
      // Maybe you want ot check if the new value is not greater than the current timer value...
      // check that fireRate is no 0 or negative, big enough
    }
 }
 
 void Start()
 {
     timer = fireRate;
     StartCoroutine(ShootTimer());
 }
 
 private IEnumerator ShootTimer()
 {
     while(true){
         while(timer > 0)
         {
              timer -= Time.deltaTime;
              yield return null;
         }
         Shoot();
         timer = fireRate;
     }
 }
 
               Well, try that, let's see if I got it working on first try...
Where do i put this script in? upgrade or the firerate? and where is my create instance?
That is in the TurretShooting to replace the InvokeRepeating.
Shoot => shootcannonball
Like this?
 using UnityEngine;
 using System.Collections;
 
 public class TurretShooting : $$anonymous$$onoBehaviour {
     
     //public Rigidbody cannonball;
     //public Transform cannonend;
     //private float cannonballspeed = 1500f;
     private float timer = 0f;
     private float fireRate = 3.0f;
     public float FireRate
     {
         get {return fireRate;}
         set{
             fireRate -= value;
             timer = fireRate;
         }
     }
     
     public void Start () {
         //InvokeRepeating("shootcannonball", 1, firerate);
         timer = fireRate;
         StartCoroutine(ShootTimer());
     }
     //void shootcannonball () {
         //Rigidbody cannonballrig;
         //cannonballrig = Instantiate (cannonball, cannonend.position, cannonend.rotation) as Rigidbody;
         //cannonballrig.AddForce (-cannonend.forward * cannonballspeed);
     //}
 
     private IEnumerator ShootTimer()
     {
         while(true){
             while(timer > 0)
             {
                 timer -= Time.deltaTime;
                 yield return null;
             }
             Shoot();
             timer = fireRate;
         }
 }
 
 
                  Or like this ? :
 using UnityEngine;
 using System.Collections;
 
 public class TurretShooting : $$anonymous$$onoBehaviour {
     
     public Rigidbody cannonball;
     public Transform cannonend;
     private float cannonballspeed = 1500f;
     private float timer = 0f;
     private float fireRate = 3.0f;
     public float FireRate
     {
         get {return fireRate;}
         set{
             fireRate -= value;
             timer = fireRate;
         }
     }
     
     public void Start () {
         //InvokeRepeating("shootcannonball", 1, firerate);
         timer = fireRate;
         StartCoroutine(ShootTimer());
     }
     void shootcannonball () {
         Rigidbody cannonballrig;
         cannonballrig = Instantiate (cannonball, cannonend.position, cannonend.rotation) as Rigidbody;
         cannonballrig.AddForce (-cannonend.forward * cannonballspeed);
     }
 
     private IEnumerator ShootTimer()
     {
         while(true){
             while(timer > 0)
             {
                 timer -= Time.deltaTime;
                 yield return null;
             }
             shootcannonball();
             timer = fireRate;
         }
 }
 
                 Your answer
 
             Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Illuminating a 3D object's edges OnMouseOver (script in c#)? 1 Answer
Invoke Repeating not incrementing a resource 2 Answers
Where to run InvokeRepeating? 1 Answer