Search Unity

Question Capture Play time

Discussion in 'Scripting' started by mholmes, Oct 19, 2021.

  1. mholmes

    mholmes

    Joined:
    Dec 8, 2012
    Posts:
    414
    I have a few ideas how to capture play time but the main question is how do you capture if people switch between scenes? I need a object that will carry over between scenes. How do I make a object that carries over across scenes?
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,735
    ULTRA-simple static solution to a GameManager:

    https://forum.unity.com/threads/i-need-to-save-the-score-when-the-scene-resets.1168766/#post-7488068

    https://gist.github.com/kurtdekker/50faa0d78cd978375b2fe465d55b282b

    OR for a more-complex "lives as a MonoBehaviour" solution. This is the pattern I use in almost all my games:

    Simple Singleton (UnitySingleton):

    Some super-simple Singleton examples to take and modify:

    Simple Unity3D Singleton (no predefined data):

    https://gist.github.com/kurtdekker/775bb97614047072f7004d6fb9ccce30

    Unity3D Singleton with a Prefab (or a ScriptableObject) used for predefined data:

    https://gist.github.com/kurtdekker/2f07be6f6a844cf82110fc42a774a625

    These are pure-code solutions, do not put anything into any scene, just access it via .Instance!

    If it is a GameManager, when the game is over, make a function in that singleton that Destroys itself so the next time you access it you get a fresh one, something like:

    Code (csharp):
    1. public void DestroyThyself()
    2. {
    3.    Destroy(gameObject);
    4.    Instance = null;    // because destroy doesn't happen until end of frame
    5. }
     
    Joe-Censored likes this.
  3. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    While @Kurt-Dekker gives a more thorough answer for what you're trying to achieve, the most direct answer to this question is to call DontDestroyOnLoad on a script attached to a GameObject at the root of the scene. The DontDestroyOnLoad object you will see is then moved to its own fake DontDestroyOnLoad scene in the scene hierarchy, where it survives any scene load or unload without being destroyed automatically.

    https://docs.unity3d.com/ScriptReference/Object.DontDestroyOnLoad.html
     
    Kurt-Dekker likes this.
  4. mholmes

    mholmes

    Joined:
    Dec 8, 2012
    Posts:
    414
    Thanks Guys. Can I capture exit application as well? would that be something like OnExit?
     
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,735
    You can but it's not really defined how much you can do after receiving a quit message... some platforms you can do a lot, others throw you out of the pool of running processes fairly rapidly, so it is best to keep it brief and to the point, perhaps write some values to disk, that's about it.
     
  6. mholmes

    mholmes

    Joined:
    Dec 8, 2012
    Posts:
    414
    I think I got it. Here is my code in case its needed:


    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Core_Analytics_Manager : MonoBehaviour
    6. {
    7.     public static Core_Analytics_Manager _Analytics_Manager;
    8.     public static bool _Playing_Product;
    9.  
    10.     private float PlayTime = 0f;
    11.     private decimal HoursPlayed = 0;
    12.  
    13.     void Awake()
    14.     {
    15.         if(_Analytics_Manager == null)
    16.         {
    17.             DontDestroyOnLoad(gameObject);
    18.             _Analytics_Manager = this;
    19.         }
    20.         else if(_Analytics_Manager != this)
    21.         {
    22.             Destroy(gameObject);
    23.         }
    24.     }
    25.  
    26.     private void Update()
    27.     {
    28.         //3600 seconds in 1 hour
    29.         if (_Playing_Product)
    30.         {
    31.             PlayTime += Time.deltaTime;
    32.             HoursPlayed = (Mathf.RoundToInt(PlayTime)/3600);
    33.         }
    34.     }
    35.  
    36.     static void Quit()
    37.     {
    38.         _Playing_Product = false;
    39.         //Save Play Time
    40.     }
    41. }
     
  7. I bet you're trying it in the editor. There is no Quit in the editor.
    https://docs.unity3d.com/ScriptReference/Application.Quit.html

    If you want to test in the editor, you need to use the https://docs.unity3d.com/ScriptReference/EditorApplication-playModeStateChanged.html

    Also read the quitting's documentation page carefully, you don't have quitting on some platforms or you only have limited functionality.
     
  8. mholmes

    mholmes

    Joined:
    Dec 8, 2012
    Posts:
    414
    Use
    Code (CSharp):
    1. void OnApplicationQuit()
    Instead Of Quit
     
  9. mholmes

    mholmes

    Joined:
    Dec 8, 2012
    Posts:
    414
    I built the game and tested it. that's how I knew it was not working. It never hit my API. So I tried the
    1. void OnApplicationQuit() and that worked.