自分用まとめ。随時更新。
【Unite 2017 Tokyo】Unity最適化講座 ~スペシャリストが教えるメモリとCPU使用率の負担最小化テクニック~
transformを動かすとその度に変更通知が送られる。
void Update(){
transform.position + new Vector3(1f,1f,1f);
transform.rotation + Quaternion.Euler(45f,45f,45f);
}
この例だと2回送信されるので無駄が生じる。transform.position + new Vector3(1f,1f,1f);
transform.rotation + Quaternion.Euler(45f,45f,45f);
}
void Update(){
transform.SetPositionAndRotation(
transform.position + new Vector3(1f,1f,1f);
transform.rotation + Quaternion.Euler(45f,45f,45f);
);
}
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の場合は特別。transform.SetPositionAndRotation(...)
}
Rigidbody rb;
void Awake(){
db = GetComponent<Rigidbody>();
}
void Update(){
rb.MovePosition(...);
rb.MoveRotation(...);
}
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 DebuggerとUI 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"が返却されれば成功
【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あたり)
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が発生するコードを記述しない)
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命令などの具体的な話
AOS SOA、キャッシュを意識したプログラミング、ビット演算、SIMD命令などの具体的な話
プログラムを高速化する話 from 京大 マイコンクラブ
コメント
コメントを投稿