Hi guys! So I have written an energy refill script:
if(Reference.energy < 20 && PlayerPrefs.GetInt("Key_2") == 0)
{
PlayerPrefs.SetString("Key_1", DateTime.Now.ToString());
PlayerPrefs.SetInt("Key_2", 1);
Debug.Log("Refill");
}
if(PlayerPrefs.GetInt("Key_2") == 1)
{
refillTime = DateTime.Now.Subtract(DateTime.Parse(PlayerPrefs.GetString("Key_1")));
if(refillTime.TotalSeconds > 5)
//Refill time of 5 seconds for testing purposes
{
Reference.energy += (int)refillTime.TotalSeconds / 5;
counter.text = "Energy: " + Reference.energy + "/20";
PlayerPrefs.SetInt("Key_0", Reference.energy);
PlayerPrefs.SetInt("Key_2", 0);
}
It works beautifully when I’m playing the game, every five seconds the energy counter goes up by 1. However, if I exit my game for 20 seconds, and the energy should increase by 4, it still stays on the same amount as it was when I exited my game. WHy is this happening and how can I fix it? Thanks!
I just did some testing and this seems to work perfectly, it should also be more efficient than your version.
using System;
using UnityEngine;
public class EnergyTest : MonoBehaviour {
int energy;
int nextTimeToGiveEnergy = 5;
void Start()
{
energy = PlayerPrefs.GetInt("energy"); //get energy from Prefs
int timeOffline = (int)DateTime.Now.Subtract(DateTime.Parse(PlayerPrefs.GetString("lastTimeEnergyGiven"))).TotalSeconds; //calculate time offline as an int
while (timeOffline > 5 && energy < 20) //doing this so we can limit energy to 20
{
energy += 1;
timeOffline -= 5;
}
PlayerPrefs.SetInt("energy", energy); //save energy again
PlayerPrefs.SetString("lastTimeEnergyGiven", DateTime.Now.ToString()); //save the time, because the user just got energy
Debug.Log(energy); //testing purposes
}
void Update () {
if (Time.time >= nextTimeToGiveEnergy) //Time.time is incremented every second, with 0 being the second the game began.
{ //Code is ran every 5 seconds, it also is more efficient than DateTime.now
nextTimeToGiveEnergy += 5; //It will run again in 5 seconds
energy++; //increment energy by one
PlayerPrefs.GetInt("energy", energy); //save energy
PlayerPrefs.SetString("lastTimeEnergyGiven", DateTime.Now.ToString()); //save the last time energy was given, cannot be Time.time
Debug.Log(energy); //testing purposes
}
}
}
There are some obvious problems that would show when the energy is refilled less frequently, let’s say 5 minutes. For example, if you were offline for 3 minutes, when logging in the timer would reset. This is fairly easy to fix, but I’ll leave the code up to you.
I am also not sure if having the loop this way is faster than having a coroutine with an infinite loop and a yield new WaitForSeconds(5)
Just realised, another problem is the fact that the first time you run it, it will throw an error, because PlayerPrefs.GetString(“lastTimeEnergyGiven”) will return null, and Date time won’t be able to cast it
maybe you are running into an issue when casting it as an int. try changing line 13 to this,
Reference.energy += Mathf.FloorToInt(refillTime.TotalSeconds / 5);