0
\$\begingroup\$

It's showing minutes seconds milliseconds but I want to show also the hours.

At the top:

private int seconds; // Seconds.
private int minutes; // Minutes.
private int hours;   // Hours.

In Update:

void Update()
{
if (seconds < 1)
        {
            seconds = 59;
            minutes--;
        }
        if (minutes < 1)
        {
            minutes = 59;
            hours--;
        }
        if (hours < 1)
        {
            hours = 59;
        }
        seconds--;

        EditorGUILayout.LabelField("Next: ", hours.ToString() + ":" + minutes.ToString() + ":" + seconds.ToString());

Update, This is what I tried:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;

public class Timer : EditorWindow
{

    private static Timer editor;
    private static int width = 300;
    private static int height = 110;
    private static int x = 0;
    private static int y = 0;
    int totalSeconds;

    [MenuItem("Window/Timer")]
    static void ShowEditor()
    {
        editor = EditorWindow.GetWindow<Timer>();
        editor.Init();
    }

    public void Init()
    {
        StartTimer(1, 1, 50);
        Debug.Log("The level will now be saved automatically");
    }

    void OnGUI()
    {
        EditorGUILayout.LabelField("Next: ", TimeString());
    }

    public void StartTimer(int hours, int minutes, int seconds)
    {
        totalSeconds = seconds + 60 * minutes + 60 * 60 * hours;
    }

    string TimeString()
    {
        return string.Format("{0:00}:{1:00}:{2:00}",
                      totalSeconds / (60 * 60),   // Hours
                      (totalSeconds / 60) % 60, // Minutes
                      totalSeconds % 60);     // Seconds
    }
}

But the timer is not moving not counting back it stay still. I tried also to move the line:

StartTimer(1, 1, 50);

To be inside the OnGUI before the LabelField.

\$\endgroup\$
4
  • 2
    \$\begingroup\$ You claim your code shows milliseconds, however there is no mention of milliseconds in the code you provided. There must be some mix-up there. \$\endgroup\$
    – Theraot
    Sep 26 '18 at 11:36
  • 1
    \$\begingroup\$ Is this something you want to tick down in realtime? Since you were subtracting 1 "second" in every update (which generally fires 30+ times per second) regardless of how much deltaTime had actually passed, I assumed you were trying to make a decorative countdown effect. If you really want to measure real time in the editor and trigger a save after a particular realtime interval, why not use a literal, standard Timer? \$\endgroup\$
    – DMGregory
    Sep 26 '18 at 12:30
  • \$\begingroup\$ @DMGregory I'm using now the Timers and using Timer and it's working fine for hours minutes seconds but if I want to add also milliseconds ? How can I do it inside the elapsed event T_Elapsed(object sender, ElapsedEventArgs e) ? Inside the elapsed event I can make the hours minutes seconds but not milliseconds. \$\endgroup\$ Sep 26 '18 at 13:58
  • 1
    \$\begingroup\$ I've edited my comment to clarify that the Timer is for triggering your save once the time is up. You can use a Stopwatch for tracking the countdown, or a TimeSpan as Phillipp demonstrates in an answer. \$\endgroup\$
    – DMGregory
    Sep 26 '18 at 14:20
4
\$\begingroup\$

Writing your own date and time handling code from scratch is a path towards agony and despair. It is usually far better to use the time handling features provided by your platform. In the case of C#, the standard library offers you a handy TimeSpan class.

 TimeSpan timer = new TimeSpan(1, 1, 50);
 Debug.Log("The timer is set to " + timer.ToString("hh\\:mm\\:ss"));

The class also has a bunch of methods which allow you to modify the value in an easy and painless way. For example, if you want the Update method of a MonoBehaviour to reduce the remaining time:

 Update() {
    TimeSpan deltaTimeSpan = TimeSpan.FromSeconds(Time.deltaTime);
    timer = timer.Subtract(deltaTimeSpan);
    Debug.Log("Time left: " + timer.ToString("hh\\:mm\\:ss"));
 }
\$\endgroup\$
1
  • \$\begingroup\$ You could also use timer = timer.AddSeconds(-Time.deltaTime); to be more succinct \$\endgroup\$
    – Ed Marty
    Sep 26 '18 at 23:08
2
\$\begingroup\$

Your logic for advancing the time from one variable to the other is not correct. It skips over second 0 every minute, and minute 0 every hour.

You can simplify this greatly by storing just one variable internally, and splitting out the hours/minutes only when needed:

int totalSeconds;

public void StartTimer(int hours, int minutes, int seconds) {
    totalSeconds = seconds + 60 * minutes + 60*60 * hours;
}

string TimeString() {
    return string.format("{0:00}:{1:00}:{2:00}", 
                  totalSeconds/(60*60),   // Hours
                  (totalSeconds/60) % 60, // Minutes
                  totalSeconds % 60);     // Seconds
}
\$\endgroup\$
2
  • \$\begingroup\$ I tried I'm using EditorWindow and OnGUI. But it's not working. Updated my question with what I did. Either using the StartTimer in the Init or inside the OnGUI not starting the timer. \$\endgroup\$ Sep 26 '18 at 12:25
  • 1
    \$\begingroup\$ @BenziAvrumi it looks like you forgot to decrement your totalSeconds variable somewhere. All I showed here are the methods to initialize the time and convert it to a string. Counting it down at the frequency you want is still up to you. \$\endgroup\$
    – DMGregory
    Sep 26 '18 at 12:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.