SimpleAnimationとDoTweenを比較してみた

はじめに

Applibotの20卒クライアントエンジニアの田中です!

今回はAnimationとDoTweenのどちらがパフォーマンス的に良いのか検証してみました。
また、お手元で検証される場合のFPSはPCのスペックごとに異なるので、今回は「比較」した点を見ていただけたらと思います。

本記事の流れ

  • 背景と目的
  • SimpleAnimationについて
  • Unity旧Animationとの比較
  • DoTweenについて
  • 他のTween系と比較
  • Animationの検証 (前検証・比較・+α)
  • 考察・まとめ

背景・目的

Applibotでは1つのゲーム内で大きく分けて「インゲーム」と「アウトゲーム」の2種類が存在します。
インゲームはゲームのメインとなる部分で、例としてキャラクターと敵が戦うようなシステムだったり、チーム同士を戦わせるシステム全体のことを表しています。
また、アウトゲームはキャラクタを強化したり、ゲームの設定を行ったりとインゲーム以外の画面を表しています。

私はアウトゲームの担当でUIの多い画面を開発しています。
そのため、ユーザー体験の向上のために、UIアニメーションのパフォーマンス検証を行いました。

アウトゲームのUIアニメーションは主にSimpleAnimationDoTweenを使っていたので、
これらのどちらがパフォーマンス的に良いかを比較していきます。

SimpleAnimationについて

SimpleAnimationはUnityの新しいアニメーションシステムに対応した、Animation単体を流すこと のできる機能になります。RunTime Animation Controllerを利用しないので、Animationの管理が楽になります。機能としては、Animationコンポーネントと同じ役割になります。

以下のリンクからpackageをダウンロードできます。
https://github.com/Unity-Technologies/SimpleAnimation

Unity旧Animationとの比較

Unityの「Animation」コンポーネントと比較すると項目としてはほとんど変わりません。

強いて言うならSimpleAnimationのAnimationsがKeyから取得できるようになっています。

UnityのAnimationコンポーネントはUnity4以前の旧アニメーションシステムなので非推奨になっており、以下のようにinspectorのDebugモードからanimationファイルのLegacy項目のチェックを外すと旧Animationコンポーネントでは使えなくなります。

しかし、SimpleAnimationでは、Legacyにチェックが入っていないAnimationファイルを使用することができます。

また、旧Animationのほうが良い場合もあり、単純なアニメーションの場合は旧アニメーションシステムを使ったほうが早いです。理由は以下になります。

ブレンディングなしで 1 つの アニメーションクリップ を再生すると、Unity は 古いアニメーションシステム を使うよりも遅くなる場合があります。古いシステムは非常に直接的で、カーブをサンプリングし、直接 Transform に書き込みます。Unity の現在のアニメーションシステムには、ブレンディングに使用する一時的なバッファがあり、サンプリングされたカーブやその他のデータの追加コピーを行います。現在のシステムレイアウトはアニメーションブレンディングとより複雑な設定のために最適化されています。

Unityマニュアル パフォーマンスと最適化 より

DoTweenについて

Tweenとは「Between」が由来で、開始時と終了時の情報を入力として、途中の経過状態を補完して表現する方法で、DoTweenのほかに、LeanTweenやiTweenなどあります。

他のTween系との比較

DoTween公式より、他のTween系とのパフォーマンス比較で、以下のような検証結果が出されていました。DoTweenは起動時間はLeanTweenに劣るそうです。平均FPSは一番高いです。

DoTween公式より「他のエンジンとの比較」

LeanTweenは起動時のパフォーマンスが良く、UnityのGCによるメモリ領域の開放が発生しないそうです。起動時を含めパフォーマンス的にはLeanTweenのほうが良いと思われます。

以下のサイトより引用
【Unity】【Tween】Unity でどのTweenアセットを使うか悩んでいる方へ

しかし、LeanTweenの注意点として以下のようにも書かれていました。

・LeanTween.Complete() のような強制的にCompleteを呼べない

・LeanTween.Stop() のように停止できない

・Shake のような演出系の操作はsequence で頑張って実装しないといけない

・RectTransform.anchoredPosition をmove できない

【Unity】【Tween】Unity でどのTweenアセットを使うか悩んでいる方へより

また、それぞれの実装できる内容が気になったので、少し調べて以下のようにまとめました。

比較項目LeanTweenDoTween
処理完了〜.setOnComplete(メソッド)Tweener.OnComplete(完了後メソッド)
停止LearnTween.cancel(gameObject)Tweener.Kill()
演出系の操作独自で実装する必要ありJump、Punch、Shake
移動.move().DOMove()

LeanTweenDoTweenのような便利なAPIがありません。DoTweenのほうがAPIが豊富のため使いやすい 基本の移動、回転、拡大縮小の他にJump、Punch、Shakeなどの頻繁に使うものも機能で追加されています。

パフォーマンスの差はあまり気にならないので、使いやすいDoTweenを選んでいる人が多そうでした。

検証における作業環境

今回は以下の作業環境で検証しました。

Unity 2020.3.25f1
DoTween v1.2.632 

Animationの検証(前検証)

【3Dオブジェクトのアニメーション比較】

まず、Unity公式で気になった記載があったので、移動、回転、拡大縮小を3Dオブジェクト内で比較検証を行いました。

スケールカーブのアニメーションは、移動や回転のアニメーションよりも非常に処理コストがかかります。パフォーマンスを改善する場合は、スケールアニメーションを避けます。

Unity公式 最適化とパフォーマンス より

目的
3Dの移動、回転、拡大縮小それぞれの負荷チェック

条件
100個の親オブジェクトの生成、親オブジェクトには100個の子オブジェクト をそれぞれ生成。SimpleAnimationを使用

結果

FPS最大FPS最小
拡大縮小74.4166966.91605
移動99.5720491.62695
回転98.2058878.70071
3Dの移動、回転、拡大縮小それぞれの負荷比較結果

結果を見ると3Dの場合は拡大縮小が一番負荷がかかっていました。

【UIのアニメーション比較】

次に、UIの負荷比較も行ってみました。

目的
UIの移動、回転、拡大縮小それぞれの負荷チェック

条件
100個の親オブジェクトの生成、親オブジェクトには100個の子オブジェクト をそれぞれ生成。SimpleAnimationを使用

結果

FPS最大FPS最小
拡大縮小27.5773224.52138
移動27.4874122.47707
回転27.2457125.21078
2Dの移動、回転、拡大縮小それぞれの負荷比較結果

結果を見るとUIの場合はあまり変わりませんでした。

【3Dと2Dの処理比較】

以上の検証結果の理由を調べたところ、処理の内容が全く違うことがわかりました。3Dオブジェクトの場合はCamera、UIの場合はCavasがそれぞれ描画処理を行ってます。

今回はアウトゲームの検証ですので、UIを中心に検証していきます。

Animationの検証(比較)

それでは、SimpleAnimationとDoTweenの比較をしていきます。

負荷の検証の仕方として、オブジェクトの数を徐々に増やしてどれだけ負荷がかかっているかの変化を移動、回転、拡大縮小、透過をそれぞれ見てきます。

【SimpleAnimationとDoTweenの比較】

目的
SimpleAnimationDoTweenの移動、回転、拡大縮小、透過の比較

条件
100個の親オブジェクトの生成 親オブジェクトには0〜100個の子オブジェクトをそれぞれ生成

結果

このグラフの説明として、縦軸がFPSで、横軸が子オブジェクトの数になります。SimpleAnimationの場合、移動、回転、透過は負荷はあまり変わらず、拡大縮小だけ他と比べて負荷が軽い印象でした。

また、DoTweenの場合、移動、回転、拡大縮小、透過の負荷はあまり変わリませんでした。

2つを比較してみるとオブジェクトが少ない場合、SimpleAnimationのほうが負荷がかかっていた。profilerよりSimpleAnimationはAnimation.Updateが負荷の発生している原因だとわかりました。主にAnimator.WritePropertiesで負荷がかかっています。

SimpleAnimationの処理

DoTweenの場合、DOTweenComponent.Updateのような同様のUpdate処理が走っていますが、Animation.Update処理時間0.61msに対し、DOTweenComponent.Update処理時間0.068msとかなり処理速度は軽くなっています。

DoTweenの処理

SimpleAnimationが少し負荷がかかっている原因として、前述した内容も含まれていると思われます。

ブレンディングなしで 1 つの アニメーションクリップ を再生すると、Unity は 古いアニメーションシステム を使うよりも遅くなる場合があります。

Unityマニュアル パフォーマンスと最適化 より

Animation検証(+α)

様々なパターンで検証していく中で面白い結果が出たものを紹介します。

【オブジェクトの表示非表示】

目的
SimpleAnimationDoTweenの透過アニメーション比較
Alphaの変更はCanvasGroupを使用

条件
100個の親オブジェクトの生成 親オブジェクトには0〜100個の子オブジェクトをそれぞれ生成
表示非表示の制御はオブジェクトのSetActive

結果

以上の結果より、表示のときのオブジェクトの場合は当然のことながら負荷はかからず、非表示のオブジェクトがあるだけで負荷がかかっていました。移動、回転、拡大縮小ではこの現象は起きませんでした。

理由として、CanvasGroupをつけていたため、OnCanvasGroupChangedにより、 非表示のオブジェクトにもアクセスしていた事がわかりました。

SimpleAnimation処理の内容
DoTween処理の内容

直接表示中のImageコンポーネントのalphaをいじる方向で処理を変更すれば、負荷は軽減されそうです。

【オブジェクトを重ねて表示】

目的
DoTweenの移動アニメーションでオブジェクトをバラバラの表示と重ねて表示の比較

条件
100個の親オブジェクトの生成 親オブジェクトには0〜100個の子オブジェクトをそれぞれ生成

結果

DoTweenの移動アニメーションFPS

オブジェクトが重なっているときにも負荷がかかります。

同じキャンバス上で、オブジェクトを重ねたときにCanvas.RenderOverlaysの処理が重くなっていました。

オブジェクトを重ねたときの処理内容
オブジェクトをバラバラに表示したときの処理内容

まとめ・考察

  • SimpleAnimationよりDoTweenのほうが処理負荷は軽い印象 →Animation.Update()が入っている分負荷が大きい
  • CanvasGroupコンポーネントの透過を変更する場合は、非表示のオブジェクトも 処理対象に含む
  • 同じCanvas上でオブジェクトは重ねすぎないようにする →Canvasは動くオブジェクト、動かないオブジェクトでまとめて分割したほうが良い

最後に

今回はUIアニメーションの負荷検証を行いました。小規模の開発ではあまり重要視されない内容だと思われますが、ゲームの内容が拡大していくごとに負荷の重要度は高くなります。個人的にもためになった検証だったなと感じました。この内容が皆様のお役に立てれば幸いです。


関連記事一覧

  1. この記事へのコメントはありません。