Skip to content

Instantly share code, notes, and snippets.

@restush
Last active October 20, 2023 17:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save restush/43b800a6b361ab69d148b707fa7d1cd8 to your computer and use it in GitHub Desktop.
Save restush/43b800a6b361ab69d148b707fa7d1cd8 to your computer and use it in GitHub Desktop.
CustomTime for Naninovel in Unity
/// <summary> Custom Unity Time based on <see cref="System.Diagnostics.Stopwatch"/> </summary>
public class CustomTime : ITime
{
public float TimeScale { get; set; }
public float Time { get; private set; }
public float DeltaTime { get; private set; }
public float UnscaledTime { get; private set; }
public float UnscaledDeltaTime { get; private set; }
public int FrameCount { get; private set; }
private readonly System.Diagnostics.Stopwatch stopwatch;
private readonly float defaultTimeScale; // default `TimeScale` that set in first instance
private float lastTimeScale; // last `TimeScale` before changed
private long lastElapsedTicks; // last Stopwatch's ticks in Update method
public CustomTime(float timeScale = 1f)
{
stopwatch = new System.Diagnostics.Stopwatch();
stopwatch.Start();
lastElapsedTicks = stopwatch.ElapsedTicks;
TimeScale = timeScale;
lastTimeScale = timeScale;
defaultTimeScale = timeScale;
}
/// <summary>Calculate `Time` and `DeltaTime` based on current frame.</summary>
/// <remarks>Important: Call this method in Monobehaviour.Update()</remarks>
public void Update()
{
CalculateDeltaTime();
FrameCount++;
void CalculateDeltaTime()
{
long currentElapsedTicks = stopwatch.ElapsedTicks;
UnscaledTime = stopwatch.ElapsedMilliseconds * 0.001f;
UnscaledDeltaTime = (currentElapsedTicks - lastElapsedTicks) * (1.0f / System.Diagnostics.Stopwatch.Frequency);
DeltaTime = UnscaledDeltaTime * TimeScale;
Time += DeltaTime;
lastElapsedTicks = currentElapsedTicks;
}
}
/// <summary>Freeze the time.</summary>
/// <remarks>Info: Before changed, the `TimeScale` cached to <see cref="lastTimeScale"/>.</remarks>
public void Pause()
{
lastTimeScale = TimeScale;
TimeScale = 0;
}
/// <summary>Resume the time.</summary>
/// <remarks>Info: Resume the time based on lastTimeScale.</remarks>
public void Resume()
{
TimeScale = lastTimeScale;
}
/// <summary>Set default `TimeScale` that set in first instance.</summary>
public void SetDefaultSpeed() => TimeScale = defaultTimeScale;
public void Speed1x() => TimeScale = 1;
public void Speed2x() => TimeScale = 2;
public void Speed5x() => TimeScale = 5;
public void Speed10x() => TimeScale = 10;
}
public class Initialize : MonoBehaviour
{
private ITime time;
private async UniTask Start()
{
time = new CustomTime();
await RuntimeInitializer.InitializeAsync(time: time);
}
private void Update()
{
if (this.time is CustomTime time)
time.Update();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment