[Unity] 最適化まとめ

自分用まとめ。随時更新。

【Unite 2017 Tokyo】Unity最適化講座 ~スペシャリストが教えるメモリとCPU使用率の負担最小化テクニック~


transformを動かすとその度に変更通知が送られる。
void Update(){
    transform.position + new Vector3(1f,1f,1f);
    transform.rotation + Quaternion.Euler(45f,45f,45f);
}
この例だと2回送信されるので無駄が生じる。

void Update(){
    transform.SetPositionAndRotation(
        transform.position + new Vector3(1f,1f,1f);
        transform.rotation + Quaternion.Euler(45f,45f,45f);
    );
}

こう書くと通知が一回なのでコストが半分になる。


ColliderはSphere < Cube < Mesh の順番で処理が重くなる。(ただしCubeよりSphereの方が静止しにくいので処理がかさみやすい。用途による)
同じ量でも散らばっている密度が高い方が重くなる。
Raycastはできる限り短く。
PhysicsLayerを設定しよう。

モバイルでの目標fpsは30。デフォルトでは50fpsだが無駄と言える。
FixedTimestepが0.04なら1秒あたり25回。作るゲームにもよるが衝突判定が少ないなら0.08以上を検討。

Rigidbodyのtransformをこのやり方で変更するのはよくない。
void Update(){
    transform.SetPositionAndRotation(...)
}
最初に言っていたことと逆になるが、Rigidbodyの場合は特別

Rigidbody rb;
void Awake(){
    db = GetComponent<Rigidbody>();
}
void Update(){
    rb.MovePosition(...);
    rb.MoveRotation(...);
}
(動画では500のオブジェクトで実験して半分のコスト);

Shadowは必要なければ極力Offに。
ロードされなければいけないのにされていない場合HideAndDontSaveをチェック。

30:00から未まとめ


【Unite 2017 Tokyo】最適化をする前に覚えておきたい技術

闇雲に始めないで計画的に。
Profilerの使い方(6:00~)

メモリの使用量が多い時(9:00~)
    C#メモリ    -  自分で書いたスクリプト。GCが走るのでリークはまずない
    Unityメモリ -  Texture,Mesh,Animationなど、リークすることがある

ロード時間が長い場合(16:50~)
    ロードが長いのか
    初期化が重いのか
    読み込むデータは適切か
    余計なデータを読んでないか

一瞬画面が固まる場合(22:00~)
    裏でロード処理などをしていないのであればほとんどの場合はGCが走っている
        C#のメモリ使用を抑える
        文字列操作はStringBuilderを使う
        Updateでのメモリ確保は控える

低いフレームレートの場合(26:20~)
60fpsなら16.6ms以内に処理を終える。30fpsなら33.36ms以内に処理を終える
Debugログは意外と重い
    ・ゲームロジックの負荷なのか
        C#なら特定する
        Unity側なら物理、UI処理、GameObjectが多すぎるなど
            モバイルでは3000,行っても5000程度に抑える
            FixedTimestepを変える
            Colliderを変える
        UIなら頂点計算が走っている
            Canvasが変わるとその中の頂点も更新される
    ・描画の負荷なのか(36:00~)
        余計な描画が入っていないか
            FameDebuggerで確認            
        Bath数(ドローコール)、SetPassが多くないか
            Batch数は描画命令を何回呼んだか
            SetPass数はマテリアル切り替えを何回呼んだか
                ➡︎モバイルなら200を超えたら見直し(100程度とも)
                できるだけ同じマテリアルで描画
                Textureをパッキング
                動かないならStaticにする
        頂点数が多すぎないか
            ポリゴンの数。あまり問題にはならない?
        描画面積が広くないか(Overdrawをしすぎていないか)
            塗るピクセル数が多いほど負荷が増える
            透明部分が多くないか(特にUI)
            イメージエフェクトは1つつける毎画面を塗り直している
        Shaderが重くないか
            大きいオブジェクトに重いShaderが付いていないか

ステップアップテクニック(46:30~)

【Unite 2017 Tokyo】Unity UI最適化ガイド 〜ベストプラクティスと新機能


UI Batchingが増える条件(6:00~)
  • canvasの数だけバッチ処理が増える
  • 違うマテリアルを使っている場合
  • 違うスプライトを使っている場合
  • 深度(z)が違う場合
  • マスクされている場合
Frame DebuggerUI Profiler(8:00~)
Frame Debuggerはバッチの状態、ビューの描画をみる
UI ProfilerはUIの描画のされ方CPU使用率を見る

Sprite Atlas(15:20~)
スプライトやテクスチャを一つのAtlasにまとめることができる

UI Shaders(24:00~)

Text Mesh Pro(26:30~)
アセット紹介

Rebuild Process(34:30~)
UIの再計算
ソースコードの紹介
動かすならPixelParfectは切った方がいい
Sub Canvases(49:30~)


【Unite 2017 Tokyo】バグを殲滅!Unityにおける実践テスト手法

※初心者向け

テスト環境
play mode(5.6から)
editor mode

Create > Testing > EditMode Test C# Script もしくは
Create > Editor Test C# Script
の中に書く

テストコードはNUnitを使う
AssertThat(検査する対象, 条件, 比較対象);
Assert.That(this.user.Name, Is.EqualTo("taro"));

"taro"が返却されれば成功

実際のテストは15:00~あたりから

【Unity】GameObjectのstatic設定についてのアレコレ



UnityDocument - レンダリングの最適化



【Unity道場】パフォーマンス最適化のポイント

その他

LightはBakedにする
Staticを使う
vsync
Pixelparfect
コールバック(Start()やUpdate())は不要なら削除
Listをforeachで回さない
gameObject.tag == "タグ"ではなく gameObject.CompareTag("タグ")を使う
キャストは(GameObject)より as GameObject の方が早い(用途によるが)
Find系、Get系メソッドは負荷が高い

OcclusionCullingで描画コストを減らす
LightProbes

[Unite 2016 Tokyo]モバイル端末向けのUnityアプリケーションの最適化実践テクニック(34:00あたり)

生成することのおおいStringはHashを利用する
static readonly int material_Color = Shader.PropertyToID("_Color");
static readonly int anim_Attack = Animator.StringToHash("attack");
material.SetColor(material_Color,Color.white);
animator.SetTrigger(anim_Attack);

Boxingを回避する(is -> cast, 値型参照型変換, boxingが発生するコードを記述しない)
テンポラリをループ内でつくらない

AOS SOA、キャッシュを意識したプログラミング、ビット演算、SIMD命令などの具体的な話

コメント