- Home /
Best way to animate incrementing/decrementing values ?
I am trying to animate text where numerical values don't simply just go from value A to value B but increment/decrement quickly over a set amount of time (meaning a set amount of frames). For example, if the game is at 30 frames per seconds and I go from 10 hit points to 40 points, I would like the hit point counter to show each increment of the hit point value (31, 32, 33 ... 38, 39, 40) over a 1 second period.
I created a simple script that can be attached to any gameObject that wants animated text:
using UnityEngine; using System.Collections;
public class TextUpdater : MonoBehaviour {
private UILabel _label;
private int _initialValue = 0;
private int _finalValue = 0;
private string _format = null;
private int _duration = 0;
private float timeElapsed = 0.0f;
public void Set(UILabel label, int initialValue, int finalValue, int duration, string format = null)
{
_label = label;
_initialValue = initialValue;
_finalValue = finalValue;
_duration = duration;
_format = format;
_label.text = _initialValue.ToString(_format);
}
void Update()
{
timeElapsed += Time.deltaTime;
if(timeElapsed > _duration)
{
_label.text = _finalValue.ToString(_format);
Destroy(this);
}
else
{
float value = Mathf.Lerp(_initialValue,_finalValue, timeElapsed/_duration);
_label.text = value.ToString(_format);
}
}
}
And here is a simple use of the script :
using UnityEngine;
using System.Collections;
public class hitPointHuD : MonoBehaviour
{
private UILabel __hitpointsLabel;
private int _hitpoints = -1;
// ------------------------------------------------------------
// Get reference to instances
// ------------------------------------------------------------
void Start ()
{
__hitpointsLabel = GetComponent<UILabel>();
}
// ------------------------------------------------------------
// Update label if hitpoint changes
// ------------------------------------------------------------
void Update ()
{
if (_hitpoints != Level.Instance.hitpoints)
{
int previousHP = _hitpoints;
_hitpoints = Level.Instance.hitpoints;
gameObject.AddComponent<sbLabelUpdater>().Set(__hitpointsLabel, previousHP, _hitpoints, 2, "N0");
}
}
}
Now this code works fine and it gives me the exact effect I want. What I do not like is the division ("timeElapsed/_duration") in the update call. Being where it is, this division will occur every frame for every UILabel that is being updated. I don't see how I could use Lerp without the ratio I get from the division. Do note that I do not absolutely want to use Lerp at all costs, it was simply the 1st solution that came to my mind.
I know I am not the first to want to create this effect... yet since it does not have an official name it has been quite hard to find examples. Does anyone know a better way to create this effect ?
Thanks !
A division per Update is utterly trivial and not worth even thinking about. Especially on modern CPUs; on $$anonymous$$e + - * / all benchmark as the same speed, and even a square root is only a few times slower (allowing for function call overhead).
Your answer
Follow this Question
Related Questions
Lerping Field Of View is buggy 1 Answer
UI Text Alpha not fading out in animation 0 Answers
Can You Animate Main Menu Title? 2 Answers
Text is too small while displaying in device 1 Answer
Unity 5 - UI Text 1 Answer