Last active
July 6, 2020 07:16
-
-
Save shanecelis/d4a26d21d9dc531bbd3e2bf33cb00259 to your computer and use it in GitHub Desktop.
Limit rate of events based on time for Unity.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Original code[1] Copyright (c) 2009 Antti Huima[2] | |
Modified code[3] Copyright (c) 2020 Shane Celis[4] | |
Licensed under the MIT License[5] | |
Original code posted to this question[6] and answer[7] on stackoverflow.com. | |
This comment generated by code-cite[8]. | |
[1]: https://stackoverflow.com/a/668327 | |
[2]: https://stackoverflow.com/users/64376/antti-huima | |
[3]: https://gist.github.com/shanecelis/d4a26d21d9dc531bbd3e2bf33cb00259 | |
[4]: http://twitter.com/shanecelis | |
[5]: https://opensource.org/licenses/MIT | |
[6]: https://stackoverflow.com/a/668327 | |
[7]: https://github.com/shanecelis/code-cite | |
*/ | |
using UnityEngine; | |
/** Limit rate of events based on time for Unity. | |
``` | |
private RateLimiter limiter = new RateLimiter(1/60f); // Allow 1 event per 60 seconds | |
// or 1 event per minute. | |
// ... | |
// Called 60 times a second. | |
void Update() { | |
if (limiter.Allow()) { | |
Debug.Log("Without a limiter this message would be logged 60 times a second."); | |
} | |
} | |
``` | |
*/ | |
public class RateLimiter { | |
public float eventsPerSecond; // units: events / second | |
private float lastCheck = -1f; // units: seconds | |
private float allowance; // units: events / second | |
public RateLimiter(float eventsPerSecond) { | |
this.eventsPerSecond = eventsPerSecond; | |
allowance = eventsPerSecond; | |
} | |
// https://stackoverflow.com/questions/667508/whats-a-good-rate-limiting-algorithm | |
/** Can allow an event within the limiter's constraints? */ | |
public bool Allow() { | |
if (lastCheck < 0) | |
lastCheck = Time.time - 1f/eventsPerSecond; | |
float current = Time.time; | |
float timePassed = current - lastCheck; | |
lastCheck = current; | |
float eventAllowance = timePassed * eventsPerSecond; // units: events | |
allowance += eventAllowance / timePassed; // units: events / second | |
if (allowance > eventsPerSecond) | |
allowance = eventsPerSecond; | |
if (eventAllowance < 1f) { | |
return false; | |
} else { | |
allowance -= 1f / timePassed; | |
return true; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment