β°Time Manager
Used to freeze/unfreeze time, do slow-motion effect
You can call TimeManager.cs anywere even if it's not replaced in scene.
namespace using Game.Core;
You should use only TimeManager to manipulate with Time freeze/unfreeze, slowMotion.
If you freeze/unfreeze Time SendFreezeChangeEvent will be Invoked. You can Subscribe to it if you need in GlobalEventsManager.cs OnTimeFreezeChanged<bool> event.
API
// you can subscribe to this event which will invoke every 1 real second tick
// to calculate game timers and etc
public static UnityEvent OnRealSecondTick;
public float DefaultTimeScale => defaultTimeScale;
public float DefaultFixedDeltaTime => defaultFixedDeltaTime;
// Resets time settings to default
public void ResetTimeToDefault() {
Time.timeScale = defaultTimeScale;
Time.fixedDeltaTime = defaultFixedDeltaTime;
}
// Freezes time by scale
public void FreezeTime();
// Unfreezes time by scale
// parameter "useDefault"=true means unfreeze and keep default timeScale
// if "useDefault"=true then last timeScale that was before time freeze will be
public void UnfreezeTime(bool useDefault = false);
// do slow-motion
public void DoSlowMotion(SlowMotionData data);
// changes time scale and stops slow-motion if was
public void SetTimeScale(float scale);
public static DateTime UnixTimeStampMillisecondsToUTCDateTime(double unixTimeStamp);
public static DateTime UnixTimeStampSecondsToUTCDateTime(double unixTimeStamp);
// formats seconds to "00:00" format (hours:minutes or minutes:seconds)
public static string FormatTime00x00(int seconds);
// run timer on TimeManager for specific seconds with tickCallback
public Coroutine RunTimerInt(float forSeconds, bool unscaled, Action<float> tickCallback);
// stop active timer on TimeManager by coroutine
public void StopTimer(ref Coroutine coroutine);Example how use TimeManager timer
// this is UI timer object, that updates text on RunTimer call till it's complete
public class TimerUI : MonoBehaviour {
[HideInInspector] public UnityEvent OnComplete = new();
[SerializeField] private Text _timerText;
public bool IsRunning => _timerCoroutine != null;
private Coroutine _timerCoroutine;
private TimeManager _timeManager;
private float _timerSecondsTotal;
private void Awake() {
if (_timeManager == null) Init();
}
public void Init() {
_timeManager = TimeManager.Instance;
}
private void OnDestroy() {
if (_timerCoroutine != null && TimeManager.IsExist) {
StopTimer();
}
}
public void RunTimer(float forSeconds, bool unscaled = true) {
if (_timeManager == null) Init();
_timeManager.StopTimer(ref _timerCoroutine);
SetSeconds(forSeconds);
_timerSecondsTotal = forSeconds;
_timerCoroutine = _timeManager.RunTimerInt(forSeconds, unscaled: unscaled, SetSeconds);
}
public void StopTimer() {
_timeManager.StopTimer(ref _timerCoroutine);
}
public void SetSeconds(float seconds) {
_timerText.text = TimeManager.FormatTime00x00((int)seconds);
if (seconds == 0) {
_timerCoroutine = null;
OnComplete.Invoke();
}
}
}
// and usage of it:
// subscribe once in Awake or something
_timerUI.OnComplete.AddListener(Lose);
// run it
_timerUI.RunTimer(forSeconds: 30f);
// stop timer if some conditions met
_timerUI.StopTimer();
// you can remove if you want to reuse it
// somewhere else with OnComplete new logic
_timerUI.OnComplete.RemoveListener(Lose);Example how use TimeManager static real second tick event
// this is example as timer, but it's not accurate
// timer error can be 1 second since OnRealSecondTick can be invoked too early
// but you can freely use it for some ingame notification or reward and etc systems!
int timeLeft;
public void OnGameStart() {
timeLeft = 10;
// subscribe to event
TimeManager.OnRealSecondTick.AddListener(UpdateTimer);
}
private void UpdateTimer() {
timerLeft--;
if (timerLeft < 0) {
OnTimeOver();
}
}
private void OnTimeOver() {
TimeManager.OnRealSecondTick.RemoveListener(UpdateTimer);
// do some actions
}Example how to do slow motion
// SO in the end of class means that this is ScriptableObject
[CreateAssetMenu(fileName = "EnemySettings",
menuName = "Configs/EnemySettings")]
public class EnemySettingsSO : ScriptableObject() {
// you can setup slow motion data in the inspector of SO asset
public SlowMotionData SlowMotionOnKill;
}
public class Enemy : Monobehaviour {
// link here your SO asset that you will create in Assets\_Main\Configs\
[SerializeField] private EnemySettingsSO _settings;
// assume that it will be called when enemy health empty
private void OnDeath() {
TimeManager.Instance.DoSlowMotion(_settings.SlowMotionOnKill);
}
}Last updated