I made HP to the tank, HP is spent when another tank hits the tank, if HP <= 0 then the tank stops for a certain number of seconds (now it's 2 seconds), while the tank is stopped, it should have a HP strip restored in n (now in 2) seconds.
I have already tried to do this using Time.deltaTime, and I managed to adjust the coefficients so that the health is filled in 2 seconds, but what if I want to change the sleep time of the tank? How can the HP be restored in n seconds so that it is smooth? It is worth noting that the values of the slider and HP are [0; 100].
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TankBattleController : MonoBehaviour
{
public float maxHealth;
public float currentHealth;
public bool isGround = true;
public bool isSleep;
public BattleController battleController;
public Transform towerTransform;
public Rigidbody rb;
public WheelCollider[] rightWheelsCol;
public WheelCollider[] leftWheelsCol;
public Transform[] rightWheelTrans;
public Transform[] leftWheelTrans;
private float _wheelSteer = 100;
private void Start()
{
rb = GetComponent<Rigidbody>();
currentHealth = maxHealth;
}
private void Update()
{
if (isSleep && currentHealth <= maxHealth)
{
battleController.SetHealthBar(currentHealth);
currentHealth = Time.deltaTime * 50;
}
}
public void TakeDamage(int damage)
{
currentHealth -= damage;
battleController.SetHealthBar(currentHealth);
if (currentHealth <= 0)
{
currentHealth = 0;
battleController.CheckScore(2, false);
StartCoroutine(TankSleep());
}
}
private IEnumerator TankSleep()
{
isSleep = true;
yield return new WaitForSeconds(2);
isSleep = false;
}
}
public void CheckScore(int score, bool whom)
{
if (whom)
{
_playerScore = score;
}
else
{
_botScore = score;
}
battleUIManager.scoreText.text = $"{_playerScore} | {_botScore}";
}
public void SetHealthBar(float value)
{
battleUIManager.healthBar.value = value;
}
CodePudding user response:
An easy way of tweaking a value over a certain time period would be to enclose it in a coroutine.
In your case, this coroutine would restore the health bar from 0 to the maximum value. The code would look like this:
// Store the health restoration time in a variable
[SerializeField]
private float healthRestorationTime = 2;
private IEnumerator RestoreHealth()
{
float timeRemaining = healthRestorationTime;
while (timeRemaining > 0)
{
// Calculate the current health multiplier. Make sure to clamp it between 0 and 1
// (we can only apply a percentage value between 0% and 100%)
float multiplier = Mathf.Clamp01(1 - timeRemaining / healthRestorationTime);
// Calculate the current health value
currentHealth = maxHeath * multiplier;
// Update the health bar
battleController.SetHealthBar(currentHealth);
// Make sure to decrease the remaining time by the amount of time passed from the last frame
timeRemaining -= Time.deltaTime;
// Wait for the next frame
yield return null;
}
// Make sure to set the health to max at the end of the coroutine
currentHealth = maxHeath;
}
Additionally, if you want the tank to only stop sleeping when the health has been fully restored, you can alter your TankSleep()
function to look like this:
private IEnumerator TankSleep()
{
isSleep = true;
yield return StartCoroutine(RestoreHealth());
isSleep = false;
}
Please note that this solution assumes that:
- The tank sleep time and the helath restoration time are the same.
- The health restoration coroutine will only be started when the health falls down to 0.
Also, make sure to remove your code from the Update function so that it doesn't try to update the health.