0

I have created a timer for my game and I need to save in a variable or a function, the time elapsed until the moment of finishing, and then show it on the screen as "Record".

I want to display on screen the shortest time achieved, when a shorter time is achieved, replace, (overwrite) the time that was until that moment.

So far I have managed to show the clock time and a text to show "Record" that only shows "00:00" since I don't know how to put my code together.

The stopwatch works and restarts every time a new game starts, but I don't know how to save the time achieved at the end of the game

How do I get the shortest time achieved to display?

My experience is sparse in C#, I have started with a simple template to experiment and make changes.

I have built the code of the clock, following an example.

On the other hand, looking for information, I see that with the PlayerPrefs method you can save and delete data.

I found another example and studied the logic to use that method on my watch, but I don't quite understand the logic and I can't get it to work.

How can I get to save the time to display it as text on the screen?

How to make it always rewrite with the shortest time obtained at the end of the game?

I show the code of my Reloj.cs which works and is displayed on the screen.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Reloj : MonoBehaviour
{
  [Tooltip("Tiempo inicial")]
  public int tiempoInicial;

  [Tooltip("Escala de tiempo del relog")]
  [Range(-10.0f, 10.0f)]
  public float escalaDeTiempo = 1;


  private Text myText;
  private float tiempoDelFrameConTimeScale = 0f;
  private float tiempoAMostrarEnSegundos = 0f;
  private float escalaDeTiempoAlPausar, escalaDeTiempoInicial;
  private bool estaPausado = false;


  void Start()
  {
    // set the timeline
    escalaDeTiempoInicial = escalaDeTiempo;

    myText = GetComponent<Text>();

    //we start the variable
    tiempoAMostrarEnSegundos = tiempoInicial;

    ActualizarRelog(tiempoInicial);

  }

  // Update is called once per frame
  void Update()
  {
    if (!estaPausado)
    {
      // the following represents the time of each frame considered the time scale
      tiempoDelFrameConTimeScale = Time.deltaTime * escalaDeTiempo;

      // the following variable accumulates the elapsed time to show it in the Relog
      tiempoAMostrarEnSegundos += tiempoDelFrameConTimeScale;
      ActualizarRelog(tiempoAMostrarEnSegundos);
    }
  }

  public void ActualizarRelog(float tiempoEnSegundos)
  {
    int minutos = 0;
    int segundos = 0;
    string textoDelReloj;

    // ensure that the time is not negative
    if (tiempoEnSegundos <= 0) tiempoEnSegundos = 0;

    // calculate seconds and minutes
    minutos = (int)tiempoEnSegundos / 60;
    tiempoEnSegundos = (int)tiempoEnSegundos % 60;

    // create the string of digital characters that form the relog
    textoDelReloj = minutos.ToString("00") + ':' + tiempoEnSegundos.ToString("00");

    // update UI text element with character string
    myText.text = textoDelReloj;
  }

  public void Pausar()
  {
    if (!estaPausado)
    {
      estaPausado = true;
      escalaDeTiempoAlPausar = escalaDeTiempo;
      escalaDeTiempo = 0;
    }
  }
}

On the other hand, I have been doing tests to try to implement the following example in my Clock, but I can't. Before asking the question here, I have looked for a solution and I have tried to learn how to do it, I have seen videos, examples, and I do not get it.

The following example, I create it by watching a video, and I get it to save the data on the screen, and delete it from a button, but I don't know how to implement it in my Clock. I imagine it would be very simple, but I can't understand the logic.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class LogicaPuntuaje : MonoBehaviour
{
  public Text textoPuntaje;
  public int numPuntaje;

  // The start is called before the first table update
  public Text textoRecord;

  void Start()
  {
    numPuntaje = 0;
    textoRecord.text = PlayerPrefs.GetInt("PuntajeRecord", 0).ToString();
  }

  // The update is called once per frame
  void Update()
  {

  }

  // button to create points by doing that I don't need
  public void PuntajeAlAzaro()
  {
    numPuntaje = Random.Range(0, 11);
    textoPuntaje.text = numPuntaje.ToString();

    if (numPuntaje > PlayerPrefs.GetInt("PuntajeRecord", 0))
    {
      PlayerPrefs.SetInt("PuntajeRecord", numPuntaje);
      textoRecord.text = numPuntaje.ToString();
    }
  }

  // function to delete the record data
  public void BorrarDatos()
  {
    PlayerPrefs.DeleteKey("PuntajeRecord");
    textoRecord.text = "00:00";
  }
}
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Estudiante
  • 92
  • 2
  • 18
  • 1
    Your values are not persistent, meaning they are lost when the app restarts. You need to save them on the disk, using PlayerPrefs to begin with https://docs.unity3d.com/ScriptReference/PlayerPrefs.html. You need to look into serialization and json to convert your data to string and use Set/GetString. – fafase Nov 22 '21 at 07:29
  • 1
    I've removed your `[unityscript]` tag because this code is C# code, and not the UnityScript language (a deprecated Javascript derivative that was created for Unity). – ProgrammingLlama Nov 22 '21 at 07:32
  • 1
    Would this answer your question [Saving/Loading data in Unity](https://stackoverflow.com/questions/40078490/saving-loading-data-in-unity) ? – derHugo Nov 22 '21 at 07:36
  • If I've used `PlayerPrefs`, forget that code snippet. but as I say, I don't know how to link it to my relog. I add the missing code. Tanks @fafase – Estudiante Nov 22 '21 at 07:36
  • The first code snippet I show works and saves the results. But I did it following a tutorial and I don't know how to add it to my Reloj.cs. It would only be to link that stop to my code, but I don't know how to do it, @derHugo – Estudiante Nov 22 '21 at 07:39
  • You need to save when a new best time value is reached, then on start you would retrieve the value. If none saved, use the default. – fafase Nov 22 '21 at 08:02
  • The first code snippet works perfectly, you create it in an empty project, with two buttons and adding punctuation. Everything works perfectly, but the problem is that. I don't know how to implement it in my code. I have understood the logic a bit, but I have tried various ways, without success. I don't know how to get it, that's why I came here to ask after 4 days testing this. I am learning and I want to discover new things, but with this I can no longer, no matter how many tests I do. I don't know to which variable or function of my clock I should add `PayerPrefs`, @fafase – Estudiante Nov 22 '21 at 08:11

1 Answers1

2
    // here is the solution:
    float currentTime; // your current timer (without logic)
    float highscore = 99999; // set it to a really high value by default
    void start()
    {
       highscore = PlayerPrefs.GetFloat("best"); // get your previous highscore
    }
    //on level completed:
    {
        if(currentTime <= highscore //your best time
        {
           highscore = currentTime;
           PlayerPrefs.SetFloat("best", highscore); // save your score
        }
    }
andAnother1
  • 168
  • 1
  • 12
  • 2
    it has PlayerPrefs data saving into it for saving your highscore even after restart the game or rebooting your device – andAnother1 Nov 22 '21 at 09:36
  • Thanks for your idea. The code in `"LogicaPuntaje.cs"` works perfectly and saves the score. The problem I have is that. or I know how to add that logic to my `"Reloj.cs"` code, which is where all the clock data is. Your code may be good, but I don't know how to include it in my Clock either. I hope you understand what I mean, I have to write in the translator and sometimes it doesn't work well. – Estudiante Nov 22 '21 at 11:03
  • its great to hear that my code is great, i also use the translator i some cases.. anyway i will handle you the code for a time script and both of us will have a nice rest day – andAnother1 Nov 22 '21 at 11:32
  • here it is! https://answers.unity.com/questions/504933/countdown-timer-in-minutessecondsmilliseconds.html#:~:text=a%20good%20start.-,using%20UnityEngine%3B,%7D,-Hope%20this%20helps – andAnother1 Nov 22 '21 at 11:34
  • Thank you for your support and dedication, but I don't think you understood my question. I think you should read the question well. My watch works perfectly and shows on the screen. What I need is to save the lowest time achieved at the end of the game, in the Record. to display it on screen – Estudiante Nov 22 '21 at 12:43
  • then you might did not read my "answer" right https://stackoverflow.com/questions/70062227/how-to-save-in-unity-the-time-obtained-in-the-game-timer-with-c/70063593?noredirect=1#:~:text=currentTime%20%3C%3D%20highscore and in your comment you said "but i dont know how to include it in my Clock either" so i send you an example how – andAnother1 Nov 22 '21 at 12:46
  • wait, what a jerk was i? Im so sorry, do you mean "transfering" a variable from one to another script? if so Public Variables got you covered. But i think you mean get the Highscore of it on your Reloj.cs right? its really simple, you can Access the PlayerPrefs savestates in every script. you just have your [Variable = PlayerPrefs.GetFloat("best");] like we did in Start() to get the saved highscore we just read out PlayerPrefs through .GetFloat (because its a float). Cheers hope i understood you this time – andAnother1 Apr 28 '22 at 13:48