Skip to content

Instantly share code, notes, and snippets.

@RiskyWilhelm
Last active September 16, 2024 21:41
Show Gist options
  • Save RiskyWilhelm/4ca8f2ed4a6eb2643b0ede70eefabecf to your computer and use it in GitHub Desktop.
Save RiskyWilhelm/4ca8f2ed4a6eb2643b0ede70eefabecf to your computer and use it in GitHub Desktop.
Unity Simple Timer/TimerRandomized (C# >= 9)
using System;
public static class RandomExtensions
{
public static float NextFloat(this Random random, float minInclusiveValue, float maxExclusiveValue)
=> (float)random.NextDouble(minInclusiveValue, maxExclusiveValue);
public static double NextDouble(this Random random, double minInclusiveValue, double maxExclusiveValue)
{
return random.NextDouble() * (maxExclusiveValue - minInclusiveValue) + minInclusiveValue;
}
}
using System;
using UnityEngine;
[Serializable]
public struct Timer : IEquatable<Timer>
{
private static readonly System.Random randomizer = new();
[SerializeField]
private TimeType _tickType;
[SerializeField]
[Min(0f)]
private float _tickSecond;
[SerializeField]
[Min(0f)]
private float _currentSecond;
public float CurrentSecond
{
get => _currentSecond;
set => _currentSecond = value;
}
public bool HasEnded
=> (_currentSecond == 0f);
public TimeType TickType
{
get => _tickType;
set => _tickType = value;
}
public float TickSecond
{
get => _tickSecond;
set => _tickSecond = value;
}
// Initialize
public Timer(float tickSecond, TimeType tickType = TimeType.Scaled)
{
this._tickSecond = tickSecond;
this._currentSecond = tickSecond;
this._tickType = tickType;
}
// Update
/// <returns> true if timer has ended </returns>
public bool Tick()
{
if (_currentSecond > 0f)
{
switch (_tickType)
{
case TimeType.Scaled:
_currentSecond -= Time.deltaTime;
break;
case TimeType.Unscaled:
_currentSecond -= Time.unscaledDeltaTime;
break;
}
}
if (_currentSecond <= 0f)
{
_currentSecond = 0f;
return true;
}
return false;
}
public void Finish()
{
_currentSecond = 0f;
}
public void Reset()
{
_currentSecond = _tickSecond;
}
public void Randomize(float maxExclusiveSeconds)
{
_tickSecond = randomizer.NextFloat(0f, maxExclusiveSeconds);
}
/// <summary> Uses <see cref="_tickSecond"/> as max exclusive value </summary>
public void Randomize()
=> Randomize(_tickSecond);
public override bool Equals(object obj)
{
return (obj is Timer timer)
&& Equals(timer);
}
public bool Equals(Timer other)
{
return (_tickType, _currentSecond, _tickSecond) == (other._tickType, other._currentSecond, other._tickSecond);
}
public override int GetHashCode()
{
return HashCode.Combine(_tickType, _currentSecond, _tickSecond);
}
public static bool operator ==(Timer left, Timer right)
{
return left.Equals(right);
}
public static bool operator !=(Timer left, Timer right)
{
return !(left == right);
}
}
public enum TimeType
{
None,
Scaled,
Unscaled,
}
@RiskyWilhelm
Copy link
Author

If C# 9 had supported record struct, it would have been better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment