Hello every one, i’m a french developper so forgive my english please! I’m working on an app for android in unity and i need help with my code. I want to make a life system like candy crush, a system that give you a pack of life after 12 hours in real life but sometimes my code works and sometimes not and i don’t know why. There is my code (i give life every 3 minutes in this code just for testing):
using UnityEngine;
using System.Collections;
using System;
public class GameHelperScript : MonoBehaviour {
public int Playerlife;
DateTime oldDate;
DateTime currentDate;
int hours;
void Start()
{
if (PlayerPrefs.GetInt("FirstStart") == 0)
{
PlayerPrefs.SetInt("FirstStart", 1);
PlayerPrefs.SetInt("PlayerLife", 5);
PlayerPrefs.SetString("sysString", System.DateTime.Now.ToString());
}
Playerlife = PlayerPrefs.GetInt("PlayerLife");
}
void Update ()
{
DateTime.TryParse (PlayerPrefs.GetString ("sysString"), out oldDate);
currentDate = System.DateTime.Now;
hours = currentDate.Minute - oldDate.Minute;
if (hours >= 3)
{
PlayerPrefs.SetInt("PlayerLife", 5);
Playerlife = PlayerPrefs.GetInt("PlayerLife");
PlayerPrefs.SetString("sysString", System.DateTime.Now.ToString());
}
}
}
Your problem probably is here
hours = currentDate.Minute - oldDate.Minute;
DateTime.Minute means “minutes in this hour”. So if the timestamp “sysString” was saved at 12:59 and player continued at 13:03, hours would be -56.
You need to use TimeSpan class to keep track and compare passed time periods. Something like this (just to give you an idea, not directly applicable to your game):
using UnityEngine;
using System;
public class test : MonoBehaviour
{
private const int MAX_LIVES = 5;
// 5 seconds for testing
private static TimeSpan newLifeInterval = new TimeSpan(0,0,5);
private DateTime lostLifeTimeStamp;
private int livesLeft = MAX_LIVES;
private int amountOfIntervalsPassed;
// Update is called once per frame
void Update ()
{
if (livesLeft < MAX_LIVES)
{
TimeSpan t = DateTime.Now - lostLifeTimeStamp;
// in theory if you wait for many many years, amountOfIntervalsPassed might be bigger than fits in an int
try
{
// round down or we get a new life whenever over half of interval has passed
double intervalD = System.Math.Floor(t.TotalSeconds / newLifeInterval.TotalSeconds);
amountOfIntervalsPassed = Convert.ToInt32(intervalD);
}
catch (OverflowException)
{
// something has probably gone wrong. give full lives. normalize the situation
livesleft = MAX_LIVES;
}
if (amountOfIntervalsPassed + livesLeft >= MAX_LIVES)
{
livesLeft = MAX_LIVES;
}
Debug.Log("it's been " + t + " since lives dropped from full (now "+livesLeft+"). " + amountOfIntervalsPassed + " reloads passed. Lives Left: " + getAmountOfLives() );
}
}
[ContextMenu ("Lose Life")]
void lostLife()
{
if (livesLeft-- == MAX_LIVES)
{
// mark the timestamp only when lives drop from MAX to MAX -1
lostLifeTimeStamp = DateTime.Now;
///////////////////////////////////////////////////////////////////////////////////
// SAVE livesLeft AND lostLifeTimeStamp HERE AND RESTORE WHEN STARTING THE GAME ///
///////////////////////////////////////////////////////////////////////////////////
}
}
int getAmountOfLives()
{
return Mathf.Min(livesLeft + amountOfIntervalsPassed, MAX_LIVES);
}
}
If you add the script to a GameObject and run the Scene, you can test losing a life by right clicking on the script in the Inspector view.