Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
3
Question by L1vD3v · Mar 30, 2014 at 12:45 PM · javascripttimeloadquitsubtract

Subtract time from time

I have this code, which has an integer of 5 and then a countdown which counts down from 30 minutes. If you loose a level, it subtracts one from the integer and then every 30 minute, it adds one to the integer. Now the problem is, that when i close the game(it's for iOS) and i open it again 10 seconds later, the integer has been set back to 5 and the timer is set back to 30 and isn't running.

I have tried making a bit of the code when closing the game and loading it, but i can't seem to figure out how to subtract the time on quit with the time on load and then find the difference and subtract that with what the "counter" was on quit.

Here is my script.

  static var energyObj : int = 5;
     static var showC : boolean = true;
     private static var created = false;
     var counter : float;
     var quitGame : boolean = false;
     
     function Start()
     {
     counter = 1800;
     }
     
     function Update () {
      
      if (energyObj < 5) {
       counter -= Time.deltaTime;
          if(counter <= 0){
             energyObj += 1;
             counter = 1800;
             Debug.Log("Energy is " + energyObj); 
             }
          }
          
      energyObj = Mathf.Clamp(energyObj, 0, 5);
      
      if (energyObj > 5) {
              energyObj = 5;
         }
      if (energyObj < 0) {
              energyObj = 0;
          }
     }
     
     function OnGUI () {
     
     if (energyObj < 5) {
         var minutes = Mathf.Floor(counter / 60).ToString("00");
         var seconds = (counter % 60).ToString("00");
         if (showC == true){
         GUI.Label(new Rect(100,40,400,40),"To Next: " + minutes + ":" + seconds);
             }
         }
     
     }


Here is the code for closing and loading the game.

     function OnApplicationQuit() {
     quitGame = true;
     
     if (quitGame == true) {
         PlayerPrefs.SetFloat("lastCounter",counter);
         PlayerPrefs.SetInt("lastEnergyObj",energyObj);
         PlayerPrefs.SetString("lastTimeSaved",System.DateTime.Now.ToBinary().ToString());
         Debug.Log("time now is : " + System.DateTime.Now);
         Debug.Log("energy is : " + energyObj);
         Debug.Log("last counter is: " + counter);
     } else if (quitGame == false) {
         PlayerPrefs.GetInt("lastEnergyObj");
         PlayerPrefs.GetString("lastTimeSaved");
         PlayerPrefs.GetFloat("lastCounter");
         var timeDifference : float = System.DateTime.Now - lastTimeSaved;
         counter = timeDifference - counter;
         ernergyObj = lastEnergyObj;        
 
      }
  }
Comment
Add comment · Show 3
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image asafsitner · Mar 30, 2014 at 02:25 PM 0
Share

Haven't read it all but it was too obvious to not ask about. Why are you always setting quitGame = true; ? It makes the IF statement that follows it redundant.

avatar image L1vD3v · Mar 30, 2014 at 02:42 PM 1
Share

I saw something like it, in another thread but it wouldn't work so i just changed it although i still get some errors.

avatar image supernat · Mar 30, 2014 at 02:47 PM 0
Share

Walk us through how you expect this to work and how OnApplicationQuit works.

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Bunny83 · Mar 30, 2014 at 03:54 PM

You don't want to work with relative time values but using absolute (date-)time values of the next timeout. It's usually the simples to use the unix timestamp for such things since it's a single value which can easily modified (adding / subtracting time).

Also you shouldn't rely on OnApplicationQuit on mobile. In most cases it's possible to terminate an app. It's better to set those playerpref values during the game.

A script which provides a live-counter which automatically regenerates 1 live every 30 min could be done like this:

 //UnityScript
 
 var maxLives = 5;
 var lives = 5;
 var RegenInterval = 1800; // 30min * 60
 
 var nextLife = 0;
 
 function UnixTimestamp() : int
 {
     return System.Math.Truncate((System.DateTime.UtcNow.Subtract(new System.DateTime(1970, 1, 1))).TotalSeconds);
 }
 
 function SecondsRemaining() : int
 {
     return Mathf.Max(0,nextLife - UnixTimestamp());
 }
 
 function Start()
 {
     lives    = PlayerPrefs.GetInt("lives", maxLives);
     nextLife = PlayerPrefs.GetInt("nextLife", 0);
     InvokeRepeating("Regenerate",1,1);
 }
 
 function Regenerate()
 {
     var current = UnixTimestamp();
     if (lives < maxLives)
     {
         if (current >= nextLife)
         {
             AddLife();
             nextLife += RegenInterval; // important to do this incremental 
             
             PlayerPrefs.SetInt("nextLife", nextLife);
         }
     }
 }
 function AddLife()
 {
     if (lives < maxLives)
     {
         lives++;
         PlayerPrefs.SetInt("lives", lives);
     }
 }
 
 function SubtractLife() : boolean
 {
     if(lives <= 0)
         return false;  // no more lives left
     if (lives == maxLives)  // if we have full lives make sure the time get set to an absolute timeout
     {
         nextLife = UnixTimestamp() + RegenInterval;
     }
     PlayerPrefs.SetInt("nextLife", nextLife);
     lives--;
     PlayerPrefs.SetInt("lives", lives);
     return true;
 }


ps: Haven't tested it yet, but it should work. This script will automatically regenerate 1 life every "RegenInterval" seconds, even when the app is closed. When the app loads it reads out the last state of the "lives" and "nextLife" variables.

Keep in mind when you want to subtract a life to use the "SubtractLife" method and if you want to add a life use the AddLife method. They will ensure that the current life-counter is saved properly.

In the case that the user has used up all lives (so "lives" is 0 and nextLife is a time somewhere within the next 30 min) and he quits the app and comes back after 2 hours, the app will load the lives value "0" and the update time which now lies in the past. The Regenerate method(which checks every second if it should regenerate a life) will regenerate a life every second until it hits the value 4 (2h == 4 lives) and the countdown will continue to count down.

Comment
Add comment · Show 9 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bunny83 · Mar 30, 2014 at 04:29 PM 1
Share

Tested it in Unity and had to fix a few things ;) $$anonymous$$ainly the UnixTimestamp method which i took from StackOverflow. Just had to add the System namespace before $$anonymous$$ath and DateTime of course.

From my tests it works pretty well. I just set a 30 seconds interval and quit the game while i'm writing this comment. So i will check if the lives regenerate properly and then finish this comment ;)

So, yes, it's working ;) However It might be a good idea to call Regenerate in Start a couple of times manually so when the app is restarted it regenerates the lives immediately.

So you might want to add at the end of Start:

 for(var i = lives; i < maxLives; i++)
 {
     Regenerate();
 }


avatar image L1vD3v · Mar 30, 2014 at 05:22 PM 1
Share

Thanks you so much! It works, the only problem is that, it generates "lives" every second ins$$anonymous$$d of every 30 $$anonymous$$ute.

avatar image Bunny83 · Mar 31, 2014 at 02:23 AM 1
Share

No, it doesn't. It just generates 1 life every second after you restarted your game and several 30-$$anonymous$$ute-periods have passed already. It will regenerate 1 life every 30 real-life-$$anonymous$$utes.

Again, if you use up all your lives, quit your game and come back after 6h this script will generate 1 life for every 30-$$anonymous$$ute-period that has passed since the last time. So 6h (would be 12x30$$anonymous$$) is enough to restore all (5) lives.

$$anonymous$$ake sure the Interval is set to 1800 seconds in the inspector.

avatar image L1vD3v · Mar 31, 2014 at 12:50 PM 1
Share

Okay it's just because i want to display the "lives" and the time left, so i have made it display "5 lives" if lives is five and so on for four,three,two etc. but when i play the game and lose a level, it goes from 5 lives to 4 lives and then a second after it goes to 5 lives again. Is there a way to make it do this, but only show the displayed regeneration every 30 $$anonymous$$ute, while everything else still works?

This is the code for displaying the lives.

 function OnGUI () {
     
     if (lives == 5) {
         GUI.skin = Energy5skin;
         if (GUI.Button(Rect(10,20,80,40),"")){
         }
     }    
     if (lives == 4) {
         GUI.skin = Energy4skin;
         if (GUI.Button(Rect(10,20,80,40),"")){
         }    
     }    
 }
avatar image Bunny83 · Mar 31, 2014 at 02:19 PM 1
Share

Are you sure you used "SubtractLife()" to reduce lives like i said in my answer? Usually i would implement this in C# and use a property for "lives". Even i know UnityScript now supports properties as well, i can't remember the exact syntax ;)

You can use SubtractLife() even in an if condition like this:

 if (SubtractLife())
 {
     // Yes we still had a life and lives has been reduced by 1
 }
 else
 {
     // No more lives
 }
Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

24 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

javascript System time and date? 3 Answers

How to measure the real time differential between application runs 0 Answers

Restart game script. 1 Answer

How to load saved data from another scene? 2 Answers

Save and load data with Javascript... 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges