Проблема в вашем коде заключается в использовании System.Timers.Timer и то, как он взаимодействует с Unity. Таймер System.Timers.Timer работает на отдельном потоке, который не синхронизирован с главным потоком Unity (главным игровым потоком, где происходят все изменения UI и логики в Unity). Unity, однако, требует, чтобы вы обновляли UI только из главного потока. В результате происходит следующее:
Вы обновляете timeDisplayer.text из другого потока, что Unity просто игнорирует или не отображает (зависит от версии Unity, но в вашем случае изменения не видны).
Debug.Log() (или print()) также некорректно используется из другого потока, поэтому сообщения логируются после завершения приложения (потому что поток может завершаться только при завершении приложения).
Решение проблемы — использовать что-то, поддерживающее основной поток Unity. Рекомендуется заменить System.Timers.Timer на Coroutine или использовать InvokeRepeating().
using System;
using UnityEngine;
using TMPro;
public class TimeDisplayer : MonoBehaviour
{
public DateTime worldTime = new DateTime(2025, 1, 1, 1, 0, 0);
public TMP_Text timeDisplayer;
void Start()
{
// Запускаем корутину
StartCoroutine(UpdateWorldTime());
}
private System.Collections.IEnumerator UpdateWorldTime()
{
while (true) // Бесконечно продолжаем обновлять таймер
{
// Добавляем 1 час
worldTime = worldTime.AddHours(1);
// Обновляем текст метки
timeDisplayer.text = worldTime.ToShortTimeString() + " " + worldTime.ToLongDateString();
// Выводим в консоль
Debug.Log("Смена часа");
// Ждем 1 секунду
yield return new WaitForSeconds(1f);
}
}
}
Другой подход — использовать встроенный метод InvokeRepeating.
using System;
using UnityEngine;
using TMPro;
public class TimeDisplayer : MonoBehaviour
{
public DateTime worldTime = new DateTime(2025, 1, 1, 1, 0, 0);
public TMP_Text timeDisplayer;
void Start()
{
// Запускаем метод "addHour" каждую секунду
InvokeRepeating("AddHour", 0f, 1f);
}
private void AddHour()
{
// Добавляем 1 час
worldTime = worldTime.AddHours(1);
// Обновляем текст метки
timeDisplayer.text = worldTime.ToShortTimeString() + " " + worldTime.ToLongDateString();
// Выводим в консоль
Debug.Log("Смена часа");
}
}
Ваш изначальный подход использовал неподходящий таймер для работы в Unity. Unity не поддерживает обновление UI и вызовы таких методов, как Debug.Log(), из других потоков. Использование либо корутин, либо InvokeRepeating позволяет работать с таймером в основном игровом потоке, правильно обновляя UI.
1. TMP label - туда записывается время
- DateTime - дата, которая будет записана в TMP label
- Сам таймер
- Моя цель сделать так, чтобы каждую секунду в DateTime добавлялся один час и это было отражено на label
- Код программы:
Проблема заключается в том, что текст label меняется в инспекторе, но не на экране, сообщение "смена часа" выводится ПОСЛЕ ЗАВЕРШЕНИЯ РАБОТЫ ПРИЛОЖЕНИЯ (это я вообще не представляю как)