ss5playerForUnity1.4.5のGC Allocチューニング
はじめに
SpriteStudioのUnityPlayerが1.4.5バージョンになって、GC Allocが少なくなるような修正が入った。
ただし、GC Allocが少なくなるのにはいくつか条件があって、最悪パターンを引くと以前と同じようなゴミが発生する。てなわけで、この記事ではどのようにしたらGC Allocが少なくなるかを説明する。
参照 該当コミット
注意
playerのバージョン
1.4.5以前のバージョンはこの記事の内容は関係なし。
また、この記事で言及するやりかたはあくまでも1.4.5バージョンに対応するだけのものすごーーーーーくピンポイントなやり方であって、普遍的に通用するような手法ではない。以降のバージョンを使ってる場合は、効果があるかはちゃんと確認しよう。
GCだけがネックじゃない
この記事はあくまでもGC Allocを減らすにはどのようにすれば良いかに言及するだけで、その先にある最終的なパフォーマンスチューニングはまた別の話。メモリやCPUがネックになってるならそっちの負荷を減らすことから始めるのが普通だ。
確認方法
プロファイラを使う。
本題 GC Allocが減る条件
GC Allocが減る条件は2つある。これらは片方だけ満たしても効果がある。
条件1. メッシュの数が前フレームから変わらないとき
メッシュ数はだいたい表示パーツの数と同じと考えていい。たとえばキャラが単に腕や足を振ってるだけなんかの時はGC Allocは発生しないのに対し、表示パーツがアニメーションによって増えたり減ったりするとGC Allocが発生する。
また、ManagerDraw下にあるSpriteStudioオブジェクトが減ったり増えたりするときもGC Allocが発生する。
コード
CombineInstance[]
を使いまわすことでGC Allocを減らしている。Length
が変化すると使いまわせなくなるのでnew
する必要があり、GC Allocが発生する。
条件2. Materialが1つしかないとき
SpriteStudioの扱うMaterialはテクスチャごとに複数存在し、それぞれミックスとか加算とかのブレンドモードを表現している。Materialが1つしかないというのは、ManagerDrawが表示しているパーツがすべて同じテクスチャ、同じブレンドモードの状態を指す。
ダメなパターンだと、例えば、ManagerDrawの下にテクスチャの違う2種類のキャラを表示するとダメ。1種類のキャラしかいなくても、パーツの中にミックスパーツと加算パーツが混ざってるとかでもダメ。
ちなみに、インスペクタのMeshRendererを確認すれば、使っているMaterialを確認できる。これが1つならok。例えば↓の画像だと2つ使われている。
コード
VertexNoTriangle
のnew
は勿論のこと、InstanceMesh.triangles
でもGC Allocが発生することに注意。
(ここの処理、Mesh.CombineMeshes
の引数に結合後のsubmeshIndexを指定できれば解決するんだけどなあ。)
総合すると
上2つの条件を満たすためには、1つのManagerDrawで多くのSSオブジェクトを表示するのではなく、1つのManagerDrawに1つだけSSオブジェクトを割り当てるのが良い感じになりやすいことになる。
(当然、1キャラ内に複数のブレンドやテクスチャがあったり、スゴイ勢いでパーツ増減アニメーションが組まれてたらどうしようもない。その時はsspj作成の際のルールを見直すか、もしくはplayerを独自カスタマイズするか。)
追記:バージョン1.5.3
ss5PlayerForUnityの最新バージョンが1.5.3になってた。
GCに関しては1.4.5からさらにマシになってるので、もはやそこまでネックにはならないんじゃないかなーという感じ。Material
が複数ついててもまあまあ大丈夫。
これがどのくらいかというと、上記にある1ManagerDraw-1SSオブジェクトで構成するとGC云々よりもCPU負荷のほうが高くなる場合がある。素直にManagerDraw
をひとつだけの構成にしたほうが良いかも。実際に比較して判断しなきゃいけない。
どうしてものときのカスタム
それでもやっぱりGCがきついとき。
作業領域を弱参照でもってる箇所があるんだけど、とうぜん弱参照なのでそのうち解放されて再取得するフレームが発生する。で、このときGC Allocが発生する。この頻度はメモリの状況によりけりなので、ひょっとするとすごい勢いで再取得が行われる場合があるかもしれない。
そんなときは。以下のWeakReference
をList<int>
に換えてやる。普通のList
なので勝手に開放されなくなるわけです。
static
にList
を置くことになるので、行儀は良くない。シーン切り替え時とかに手動で開放してやること。
CameraTargetの罠
前からなんだけど、ManagerDraw
にCameraTarget
っていうフィールドがあって、ソート時にどのカメラを使うかっていうものなんだけど、カメラ探しに失敗してnullのままになるとすごい勢いでGC Allocが発生する。
Author And Source
この問題について(ss5playerForUnity1.4.5のGC Allocチューニング), 我々は、より多くの情報をここで見つけました https://qiita.com/omachi/items/c7f91f453eb119ccbbc5著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .