v1.2.420で新たに実装された、TextMeshProの拡張メソッドDOCounter()を使ってカウントダウン表示(タイマー表示)を実装してみます。
TextMeshProの拡張メソッドはPro版のみの機能なので注意。
かなり便利な機能なので、このアップデートを期にPro版を検討するのもアリかと。
DOCounter()によるカウントダウン表示
DOCounter()を使うと、こんな感じのものが簡単に実装できます。
任意のint型数値から任意のint型数値まで、任意の秒数で変化させることができます。
今回は3から0までを3秒間かけて変化させています。
罠にハマったソースコード
private void CountDown()
{
var tmpro = GetComponent<TextMeshProUGUI>();
tmpro.text = 3.ToString();
tmpro.DOCounter(3, 0, 3f).SetEase(Ease.Linear);
}
第1引数が開始時の値、第2引数が終了時の値、第3引数が時間です。
つまり3から0に向けて3秒で変化するということ。
イージングはかけずに一定変化させたいので、SetEase()でEase.Linearを指定します。
これでできるかと思ったのですが、罠がありました。
DOCounter()は以下のような挙動をするようです。
- 0.5秒間「3」を表示
- 1秒間「2」を表示
- 1秒間「1」を表示
- 0.5秒間「0」を表示
実際に見てみましょう。
左がCoroutineを使って作ったカウントダウンで、意図通りの挙動をしているものです。
右が上記ソースコードで実装した、DOCounter()を用いたカウントダウンです。
明らかにずれていますよね。
分かりやすく、0.5秒ごとに背景色を変えています。
右側のDOCounter()の方を見ていると、0.5秒早く進んでいるのが分かります。
開始時の値や終了時の値が入るかどうか、とかが思った挙動と違うのであれば納得できるのですが、どうもそうではないっぽい。
どうやら、内部的にはfloat型でカウントダウンしていて、表示は四捨五入(Round)したint型になっている様子。
これはハマってしまいました。
正しい挙動をするカウントダウン
ということで、正しい挙動をさせるためには0.5秒遅らせる必要があります。
private void CountDown()
{
var tmpro = GetComponent<TextMeshProUGUI>();
tmpro.text = 3.ToString();
tmpro.DOCounter(3, 0, 3f)
.SetEase(Ease.Linear)
.SetDelay(0.5f);
}
これで表示してみると、正しい挙動をしているのが分かります。
なぜこのような仕様なのでしょうか…。
一応意図通りの挙動はできましたが、一手間必要だった、という話でした。
コメント