【Unity】Sprite.Createが遅い・重い場合の対処法

3500x3500 のテクスチャーを 100x100 に切り出して1125個の Sprite を作成したら Ryzen 5900 なのに 30秒程度かかったため Sprite.Create の生成速度がヤバいなと思ったので調べました。

プロファイラーで見たところ1枚生成するのに 19ms もかかっていたので、これをモバイル環境で実行したらしばらく帰ってこなくなりそうなので調査しました。

こういう事は RawImage の方が得意なのかもしれませんが後でいろいろやりたいので RawImage ではなく Image コンポーネントでどうしたらいいか考えています。

問題の状況

実行環境

  • windows10
  • Ryzen 5900X
  • Unity 2020.3.14f1

Editor 上で確認

発生状況

ちなみに何がやりたかったかというと以下のような 3500x3500 の画像を100x100 に動的に切り出して

f:id:Takachan:20210724143606p:plain

以下のように再生しようとしていました。

f:id:Takachan:20210724143905g:plain

割と有名な動作らしく Sprite.Create が遅い、重いという説明をたまに見かけます。

改善方法

対策前

なんと1つの Sprite 作成に 19.21ms もかかっています。スパイクがやばい。

f:id:Takachan:20210723184317p:plain

対策後

対策すると 0.02ms になりました。

f:id:Takachan:20210723184645p:plain

19.21ms → 0.02ms なので 約960倍高速化しました。

コード

対策方法ですが、以下のように Create メソッドのオーバーロードで FullRect を指定するだけです。

// sourceTexture = Texture2D
// center = Vector2(0.5f, 0.5f);

// 遅い
var sp = Sprite.Create(this.sourceTexture, rect, center);

// 早い
var sp = 
    Sprite.Create(this.sourceTexture, rect, center, 
        this.pixelsPerUnit, 0, SpriteMeshType.FullRect); // ここまで指定する

FullRect なので、生成が軽くなりますがオーバードローの範囲が大きくなるのでそれだけ注意が必要です。

関連リンク

この方法を使って動的に画像をスライスする方法は以下で紹介しています。

takap-tech.com

参考

フォーラムにど真ん中の回答がありました。

forum.unity.com