-
Notifications
You must be signed in to change notification settings - Fork 0
Core.Utilities.SmoothValue
The SmoothValue class in SmoothValue.cs is a utility designed to interpolate a numeric value from its current state toward a target state over time. In game development, this is commonly used to prevent "teleporting" values, providing a more polished and professional feel to UI elements or gameplay mechanics.
The class manages two primary values:
-
RealValue: The "ground truth" or the actual goal (e.g., the player's actual current health). -
DisplayValue: The "smoothed" value that lags behind or catches up to the real value (e.g., the health bar's visual fill).
It supports two modes of operation determined by the fixedTime parameter in the constructor:
-
Constant Speed (
fixedTime = false): The value moves at a steady rate of "units per second." If the speed is 10 and the distance is 100, it takes 10 seconds. If the distance is 10, it takes 1 second. -
Fixed Duration (
fixedTime = true): The value uses aFixedTimerand linear interpolation (Lerp). In this mode, thespeedparameter effectively acts as the duration of the transition.
-
Update(float deltaTime): Must be called every frame. It calculates the newDisplayValue. It also includes a "snap" feature: if the display value is very close to the real value (within 0.01), it jumps to the exact value to prevent infinite micro-calculations. -
SnapToReal(): Immediately forces theDisplayValueto match theRealValue, bypassing the animation. -
IsAtRealValue: A helper property to check if the transition has finished.
- Health Bars: When a player takes damage, the health bar "drains" slowly instead of instantly disappearing.
- Score Counters: When a player earns 1,000 points, the UI digits rapidly "roll up" from the old score to the new one.
- Camera Zoom: Smoothing the transition between a wide-angle view and a zoomed-in view.
- Progress Bars: Loading screens or experience bars that fill smoothly even if the data comes in chunks.
If you want the score to always take 0.5 seconds to finish counting up, regardless of how many points were added.
// 0.5f is the duration in seconds because fixedTime is true
var scoreDisplay = new SmoothValue(initialValue: 0, speed: 0.5f, fixedTime: true);
// In your game logic when points are earned:
scoreDisplay.RealValue += 500;
// In your Update loop:
scoreDisplay.Update(deltaTime);
myUiText.Text = $"Score: {Math.Round(scoreDisplay.DisplayValue)}";If you want the health bar to drain at a constant rate (e.g., 50 HP per second).
// 50f is the units per second because fixedTime is false
var healthBar = new SmoothValue(initialValue: 100, speed: 50f, false);
// When player takes damage:
healthBar.RealValue -= 30;
// In your Update loop:
healthBar.Update(deltaTime);
healthBarRenderer.FillAmount = healthBar.DisplayValue / 100f;
// If the player dies, you might want to hide the bar instantly
if (healthBar.RealValue <= 0) {
healthBar.SnapToReal();
}You can use the state of the transition to trigger other events, like stopping a "ticking" sound effect once the value is reached.
public void Update(float deltaTime)
{
scoreValue.Update(deltaTime);
if (!scoreValue.IsAtRealValue)
{
if (!countingSound.IsPlaying) countingSound.Play();
}
else
{
countingSound.Stop();
}
}