- Home /
Increase/Decrease Value With Time - Problem
Okay, I thought I would make a new post with my problem. I'm basically trying to make a flame thrower turret that, when fires decreases its fuel, and when the fuel is empty it then refuels back to 100 - and then continues to fire.
The problem I'm having is increasing and decreasing the fuel, mainly to do with time, and frame rate. In the editor, its slow, and in the build, its really fast - and from that, I'm assuming its a frame rate problem??
Here are bits of my flame controller script:
var flameDamage : float = 0.6; private var externalSmooth : SmoothLookAt; private var particleDamage : FlameDamage;
//private var flameRange : float; private var flameOn : boolean = false; var flameParticle : ParticleEmitter;
var flameSpin : boolean = false; //var flameSpinInt : int = 720; private var speed : int = 200;
var flameAudio_start : AudioClip; var flameAudio_middle : AudioClip; var flameAudio_end : AudioClip;
// Cache externalSmooth externalSmooth = gameObject.GetComponentInChildren(SmoothLookAt);
private var audioOnce : boolean = true; private var audioOnce_end : boolean = true; var coolingBar : Transform; private var maxBar : float = 0.2;
var maxFuel : float = 100; var currentFuel : float = 100; var fillSpeed : int = 100; var emptySpeed : float = 10;
private var timer : float = 0.0f;
private var fuelEmpty : boolean = false;
function Awake(){ flameParticle.emit = false;
}
function Update () { // fixed update // Set up particleDamage \\ particleDamage = flameParticle.GetComponent(FlameDamage); if (!particleDamage) particleDamage = flameParticle.gameObject.AddComponent(FlameDamage);
particleDamage.damage = flameDamage;
if(externalSmooth.target){
flameOn = true;
flameParticle.emit = true;
}
else{
flameOn = false;
flameParticle.emit = false;
}
// Spinning FlameThrower \\
if(flameSpin == true){
externalSmooth.TurretActive = false;
Spin();
}
// fuel is full - continue to fire
if(fuelEmpty == false && flameSpin == false){
externalSmooth.TurretActive = true;
flameOn = true;
}
// fuel is empty - stop firing and refuel
else if(fuelEmpty == true){
externalSmooth.TurretActive = false;
flameOn = false;
flameParticle.emit = false;
if(currentFuel < maxFuel){
InvokeRepeating("IncreaseFuel", 0, fillSpeed);
//currentFuel += Time.deltaTime * fillSpeed;
}
if(currentFuel == maxFuel){
fuelEmpty = false;
}
}
// incase current goes above max in refuel - reset to 100
if(currentFuel > maxFuel){
currentFuel = maxFuel;
}
// flame particle functions - ON
if(flameParticle.emit == true){
if(audioOnce == true){
FlameAudio();
audioOnce = false;
}
timer = 0;
if(currentFuel > 0){
InvokeRepeating("DecreaseFuel", 0, emptySpeed);
//currentFuel -= (Time.deltaTime * emptySpeed);
//currentFuel --;
}
}
// check weather fuel is empty
if(currentFuel <= 0){
fuelEmpty = true;
}
// flame particle function - OFF \\
if(flameParticle.emit == false){
timer += Time.deltaTime;
if(timer > 0.4){
if(audioOnce_end == true){
FlameAudioEnd();
audioOnce_end = false;
}
}
}
// Cooling health bar \\
var CameraPosition = Camera.main.transform.position;
coolingBar.transform.rotation = Camera.main.transform.rotation;
coolingBar.transform.Rotate(-90, 0, 0);
coolingBar.transform.renderer.material.color = Color.cyan;
coolingBar.transform.localScale.x = (maxBar) * (currentFuel/maxFuel); //(MaxBar) * (Health/MaxHealth); ---- 0.2 * 15/15
}
function DecreaseFuel(){ currentFuel --; }
function IncreaseFuel(){ currentFuel ++; }
I would appreciate any help from this, and I apologies for repeating a post - but this is really bugging me. Cheers all!
Forgot to add: I want the fuel to decrease with time
Answer by Eric5h5 · Apr 26, 2011 at 08:31 AM
I would highly recommend using coroutines for this...using Update in that manner is kind of torturous. ;) Update is for stuff that happens every frame, but you don't want stuff to happen every frame, only sometimes. In any case I'd guess the root problem is that you're launching new instances of InvokeRepeating every frame, since at first look there's nothing preventing that from happening.
Here's a simplified example that just uses user input to decrease a fuel variable and then refills it when it runs out, but it should illustrate the general concept (switch the inspector to debug mode to see the status of the currentFuel variable at runtime, or else make it a public variable):
var maxFuel = 100.0; var fuelUsageRate = 10.0; var fuelRefillRate = 100.0; private var currentFuel : float;
function Awake () { currentFuel = maxFuel; FireControl(); }
function FireControl () { while (true) { yield WaitForInput(); yield Fire(); if (currentFuel <= 0.0) { yield Reload(); } } }
function WaitForInput () { while (!Input.GetButton("Fire1")) { yield; } }
function Fire () { while (Input.GetButton("Fire1") && currentFuel > 0.0) { currentFuel -= fuelUsageRate * Time.deltaTime; yield; } }
function Reload () { while (currentFuel < maxFuel) { currentFuel += fuelRefillRate * Time.deltaTime; yield; } currentFuel = maxFuel; }
grand master :) any chance you could do that in cSharp as well, I have difficulties doing all these coroutines stuff in c# for some reason, I miss something... thanks :) and that script is a perfect example.
@$$anonymous$$ Fabre: Well, one of the main reasons I usually use JS is that C# is quite annoying when it comes to coroutines. 1) $$anonymous$$ake sure coroutines return type IEnumerator
. 2) Use "`yield return StartCoroutine($$anonymous$$yFunction())`" ins$$anonymous$$d of "`yield $$anonymous$$yFunction()`". 3) Use "`yield return null`" ins$$anonymous$$d of "`yield`". 4) $$anonymous$$aybe something else I forgot. ;)
Oh yeah: 4) In Awake, do "`StartCoroutine(FireControl())`" ins$$anonymous$$d of "`FireControl()`".
Answer by Ashkan_gc · Apr 27, 2011 at 03:24 AM
the problem is that InvokeRepeating is called multiple times in multiple frames (whenever the condition is true) so multiple instances of your code will reduce the fuel. use coroutines for the stuff of change your Update method to check the condition and reduce the fuel itself or stoppo all invoked functions before invoking new ones.
Answer by Tommy · Apr 30, 2011 at 12:55 PM
Maybe you can do something like this:
var timeTilYouRunOutOfFuel = 5.0; var totaltTime;
function Update() {
totalTime = Time.time + timeTilYouRunOutOfFuel; if (Time.time <= totalTime) { //Keep on flaming } else if (Time.time >= totalTime) || (Time.time == totalTime) { //Crap, out of fuel, stop flaming. } }
Answer by MadeThisName · Jun 21, 2015 at 07:21 AM
Beautiful Eric5h5 Thank you for all your posts they have taught me a lot. Here is a C# version of Eric5h5 script.
using UnityEngine;
using System.Collections;
public class MYCLASSNAME : MonoBehaviour {
public float maxFuel = 100.0f;
public float fuelUsageRate = 10.0f;
public float fuelRefillRate = 100.0f;
private float currentFuel;
void Awake ()
{
currentFuel = maxFuel;
StartCoroutine (FireControl());
}
IEnumerator FireControl()
{
while (true)
{
yield return StartCoroutine (WaitForInput());
yield return StartCoroutine (Fire());
if (currentFuel <= 0.0f)
{
yield return StartCoroutine (Reload());
}
}
}
IEnumerator WaitForInput ()
{
while (!Input.GetButton("Fire1")) {
yield return 0;
}
}
IEnumerator Fire ()
{
while (Input.GetButton("Fire1") && currentFuel > 0.0f)
{
currentFuel -= fuelUsageRate * Time.deltaTime;
yield return 0;
}
}
IEnumerator Reload ()
{
while (currentFuel < maxFuel)
{
currentFuel += fuelRefillRate * Time.deltaTime;
yield return 0;
}
currentFuel = maxFuel;
}
}