I am making an energy beam firing system from a drone. In my code, I have setup a system in which the player presses and holds onto the firing button, then a countdown bar begins to countdown, and when it is empty(down to 0), the energy beam stops firing, then the button waits for sometime before it can be pressed again. All of these works fine but, my problem is: Assuming the countdown bar is not yet empty(maybe half way through), it gradually refills itself to maximum. I've tried to work on it, but I keep getting glitches on the countdown bar. How do I go about this?
EDIT: While the player presses and holds the fire button, the countdown bar begins to count down, then when the player let's go of the button about halfway through the countdown, the countdown bar gradually fills up as expected, now before the countdown bar is filled, if the player presses the fire button again, the countdown bar quickly increases(*here is the glitch) then resumes countdown again.
Here is my code:
[SerializeField] private float EnergyBeamPowerOffTime = 14; //Get this value from the hanger
[SerializeField] private float TimeToRefillEnergy = 10f;
[SerializeField] private GameObject EnergyBeamCountdown;
private Slider EnergyBeamCountdownBar;
[SerializeField] private Image EnergyBeamButtonImage;
public float EnergyBeamFillRate; //This value should be handled when the player upgrades their ships
private float EnergyBeamActiveTime;
private float EnergyRefillRate;
private bool EnergyCoroutinePaused;
private bool FiringEnergyBeam;
private bool CoolEnergyBeamDown;
private bool CoolEnergyBeamButtonDown;
private bool RefillEnergy;
private void Update()
{
EnergyBeamSetting();
}
public void OnDownShootEnergyBeam() //Let's the user click and hold on this button
{
//PlaceHolders.energyBeamFiringSFX.Play(); //Play the sound effects
droneBrain.OnDownShootEnergyBeam(); //Fire beams towards a target returned by a raycstHit(Irrelevant to this code logic)
FiringEnergyBeam = true; //Lets the countdown bar know that we started firing energy beams
StartCoroutine(EnergyBeamRoutine()); //Begins the energybar coroutine
}
public void OnUpShootEnergyBeam() //Called when the user lets go off the button
{
droneBrain.OnUpShootEnergyBeam(); //Stops firing energy beams(Irrelevant to this code logic)
FiringEnergyBeam = false; //Lets the countdown bar know that we started firing energy beams
if (EnergyBeamActiveTime > 0f)
{
EnergyBeamButtonImage.raycastTarget = true; //Allow this button to be pressed again
EnergyCoroutinePaused = true; //Pause coroutine execution
} else
EnergyCoroutinePaused = false; //Resume coroutine execution
ObjectivesChecker.NumberOfTimesEnergyBeamWasFired++; //Increase the number of times the energybeam was fired(Irrelevant to this code logic)
}
public void OnUpShootEnergybeam() //Called when the user lets go off the button
{
RefillEnergy = true; //Begin to refill energy bar
}
private void RefillEnergySettings()
{
if (RefillEnergy && !FiringEnergyBeam)
{
EnergyRefillRate = 0f; //Resets the rate of energy beam's refill
EnergyRefillRate += Time.deltaTime;
float Percent = EnergyRefillRate / TimeToRefillEnergy;
EnergyBeamCountdownBar.value = Mathf.Lerp(EnergyBeamCountdownBar.value, 1, Percent);
//EnergyBeamActiveTime = Mathf.Clamp(EnergyBeamActiveTime, EnergyBeamCountdownBar.value, 0);
EnergyBeamActiveTime = Mathf.Lerp(EnergyBeamCountdownBar.value, 0, Percent);
if (EnergyBeamCountdownBar.value >= 1)
RefillEnergy = false;
}
}
private IEnumerator EnergyBeamRoutine()
{
CoolEnergyBeamDown = true; //Lets the countdown(Energy remaining in the energy beam) begin countdown
EnergyBeamButtonImage.raycastTarget = false; //Won't allow Energybeam button to be pressed
if(EnergyBeamActiveTime > EnergyBeamPowerOffTime && !EnergyCoroutinePaused)
{
EnergyBeamActiveTime = 0f;
}
EnergyBeamCountdown.gameObject.SetActive(true); //Makes the countdown visible
yield return new WaitWhile(() => CoolEnergyBeamDown); //Waits untill CoolEnergyBeamDown is false
//Here, the beam has finished firing, we deactivate it then load the button
EnergyBeamCountdown.gameObject.SetActive(false); //Makes the countdown invisible
droneBrain.OnUpShootEnergyBeam(); //stops firing energy beam
//Now we load the button
EnergyBeamButtonImage.fillAmount = 0f; //resets the energybeam button's inactivity timer
CoolEnergyBeamButtonDown = true; //begins to prepare the energybeam button to fire again
}
private void EnergyBeamSetting()
{
if (CoolEnergyBeamDown && FiringEnergyBeam) //Conditions for the countdown bar
{
//Countdown(Energy beam's energy)
EnergyBeamActiveTime += Time.deltaTime;
float Percent = EnergyBeamActiveTime / EnergyBeamPowerOffTime;
EnergyBeamCountdownBar.value = Mathf.Lerp(1, 0, Percent);
if (EnergyBeamCountdownBar.value <= 0)
CoolEnergyBeamDown = false;
}
if (CoolEnergyBeamButtonDown) //Wait time conditions before the button can be used again
{
//Countdown for the energybeam button to prepare next fire
EnergyBeamButtonImage.fillAmount += 1f / DroneBrain.EnergyWaitTime * Time.deltaTime;
if (EnergyBeamButtonImage.fillAmount >= 1f)
{
EnergyBeamButtonImage.fillAmount = 1f;
CoolEnergyBeamButtonDown = false;
EnergyBeamButtonImage.raycastTarget = true;
EnergyBeamActiveTime = 0f;
}
else
EnergyBeamButtonImage.raycastTarget = false;
}
RefillEnergySettings();
}