Unite2017 参加しました その9
WebGL:ゲームプラットフォームとしてのWebと現在と未来
www.slideshare.net
WebGLの動機
ブラウザのプラグインを無くしたい
Web Assembly(.wasm)
対応状況
WASM MVP とは
- 最低限必要な要件が定義されている内容
- WASMモジュールの構造などに対応する、などなど
WASMの特徴
- 早い Nativeと比較して130〜150%くらいの実行時間で動くことができる。
asm.jsとWASMの違い
- WASMの方が早い。WASMは構文解析の時間が無いので早い。
- asm.jsはブラウザごとにコンパイル方法が異なる。(ベンダー依存)
WebGL
今のところ2世代
- WebGL
- WebGL2
普及率
WebGLはほとんど100%。WebGL2は50%ないくらい。
WebGL出力の注意点
WebGLでは以下のように出力される
C# ⇨ (MONO) ⇨ IL ⇨ (il2cpp) ⇨ C++ ⇨ (Clang) ⇨ LLVM IL ⇨ WASM + JS
- 結構重たい処理はJSに投げた方がスレッドが異なるので楽。
2種類のGCが存在するので注意。プロファイルする際は両方を使う
ファイルシステムはメモリ上に仮想的に作っているので、ファイルが多すぎるとメモリを圧迫することになる。
- IndexedDBもその裏ではメモリ上に展開している。
Webのこれから
- Shared Array Buffer: 共有メモリ(スレッドの実現)
- 音声処理の別スレッド化
- payment
- キャッシュ処理
Unite2017 参加しました その8
Unityライティング最新情報
www.slideshare.net
光表現について
- GI Global illumination 間接光
- Baked GI 事前に計算しておくGI
- procomputed RealTime GI リアルタイムで間接光をつくる
UnityではStaticな動かない物体に対しては、前もって間接光を計算しておく。
LightProve
空間にライトを検知するものを置いて、間接光の影響を計算しやすくするための仕組み
- 1モデル1つのproveからしか影響を受けられなかった。
- 上記が改善され、モデルが複数のproveを受けられるようになった
リアルタイムな間接光について
リアルタイムな間接光はクラスタ単位で計算される。
クラスタの大小は変更可能。
影の表現
光を遮り、影を作るためにはメッシュやポリゴンは必要となる。
メッシュやポリゴンが増えると、負荷が上がるため辛い。
動的な影と静的な影について
それぞれの影を混ぜるMixed Lighting
Mixed Lighting
- unity5.6以前では、うまくMixedすることができず、影の上に影が映ってしまうことがあった。 また、光沢の表現(スペキュラ)がお粗末だったらしい。
- MixedLightingは大きく4種類
- Subtractive
- Baked Indirect
- Shadow Mask
- Distance Shadow Mask
Subtractive
- 5.6以前のmixedに近い機能
- 影を全てTextureに焼きこんでしまう(static)
- 動的なオブジェクトに対しては計算をする。
- 動的な場合は影の色を変更することができるので、影の上に影が描画されてしまうことを避けられる。
- 影の上に影以外のmixedデメリットを引き継いでいる。光沢の表現は難しい
Baked Indirect
- 間接光のみを事前に計算しておくが、影は全てリアルタイム表現しましょう。という発想。
- 静的なオブジェクトに対しても影を描画するため辛いという欠点がある。処理時間がかかりすぎる
Shadow Mask
- 静的な影は前もって計算、動的な影はその場で計算。
- ライトは動的に描画することができるので光沢も表現することができる。
- 間接光はテクスチャに焼き込む
ShadowMaskではクッキーがつかえる
- マスクとして影を用意しているので、色や輝度を変更することは可能
- ただし、間接光はすでにTexutreに焼かれているため注意が必要。
Baked Shadow Angle
- 使用することはあるが動的な影と静的な影の差が見えてしまう。
Distance Shadow Mask
- Dynamic とShadowMaskの混合
- 距離が近い部分はDynamic,遠い部分はShadow Mask
- すなわち、近くてよく見えるところは頑張って描画するが、遠いところは低解像度でもOKとする
Unity2017.1から
QualitySettingsからShadowMaskとDistanceShadowMaskは切り替えが可能となる。
ローレベルのユーザはShadowMask、ハイエンドユーザはDistance Shadow Maskを利用する。
その他
- 影を落とすためだけのオブジェクトをおく方法もある。
- 影を落とすためだけに、低解像度のメッシュを置いても良い。
- 高解像度のポリゴンによる陰を低解像度オブジェクトで影を遮ることで作る。すなわち影を作るのはそこまでハイポリゴンは不要である。
ライトのBaked 設定
ライトの設定は大変なので、その改善方法を紹介
LightExplorer
シーン内のライト及びEmissiveの一覧を表示してくれる便利さん
Progressive LightMapper
- シーンが見えているライトを優先的にBakedしていくので、プレビューが早い
- 大まかに計算後、詳細に計算するのでやっぱりプレビューが早い
- リアルタイムGIはできない。
- ライトを焼いてから、proveを焼くので、proveに大きく依存するシーンではプレビューには時間がかかる
Unite2017 参加しました その7
最適化をする前に覚えておきたい技術
www.slideshare.net
最適化への手順
プロファイリング
処理ごとにかかった時間、メモリの使用状況を把握する。
まずは、Unityのprofiler 詳しく知りたければ、Nativeのprofiler(Xcodeとか)を使う
[window] - [プロファイラー]
対処する
メモリの使用量が多い
- 単純な使用量か、メモリリークか
- C#(MonoMemory)が原因か、Unityが原因か
C#が大きいぞ
- C#はスクリプトで使用しているメモリ。(GCされる)
- C#が確保したメモリは解放されてもC#専用領域として残ってしまう。(reserved) (Editor拡張でもメモリは取られるので、実機で確認する。)
とりあえず スクリプトを修正する
Unityメモリが大きいぞ
- TextutureやMeshなどが原因で、リークの可能性もある。
- ProfilerからAsset毎にメモリ内の容量をチェックできる。その他に公式ツールも存在する。
不必要なアセットなどを削除するようにする
ロードが長い問題
何が長いのか、初期化処理か、ロード時間か、きちんと原因を調べる profilerでロード時間をフレーム毎に見てみる。
[スクリプト].awakeが長い場合は、初期化が辛いことになっている。
- プロフィリングの時はDebugLogは止めるようにする。DebugLogは割と重い。
texture.awakeが重い
無駄なものを読み込んでいないか、やたらとリッチなTextureは存在しないかを確認する。
AssetBundleを使っている場合は、予期せず重複して読み込んでいることがあるので、注意。
一瞬ゲームが固まる問題
- GCが走った場合に起こる現象。
- profilerでCGが起きていないかを確認する。
対策
- C#スクリプトでのメモリの消費を抑える。
- 文字列の置換や検索、足し算は気をつける。
フレームレートが低い問題
FPSのフレーム間で終わらない処理をしてしまったのが原因(30FPSよりも下がると、人の体感で遅く感じてしまう)
- ゲームロジックによる負荷か、描画処理による負荷か
- profilerでrenderingをみることでわかる。
どうする
- 描画ならデザイナーさんとの交渉
- ゲームロジックなら、C#のスクリプトかUnity側の処理か。GameObejctが3000を超え始めたらC#のスクリプトの問題
- BehaviourUpdateをprofilerを見ることでわかる。
- phisicsなんとかで物理が重いのかがわかる。
- insepectorのTimemanagerでフレーム数をきちんと下げると良い。
- UIが重い場合、頂点の計算に時間がかかる
- 何かの変更があれば、すべての頂点を計算し直すため
描画の負荷で考える
- 無駄な描画をしている場合が割と多いので気をつける
- Objectの描画処理はFrameDebuggerで確認することができる。
ちなみに
- 頂点数もprofilerから確認することができる。
- 透明描画や、半透明を塗るのも結構大変。ImageEffectなどもかなり時間がかかる
Shaderはどうですか?
- ピクセル毎に細かく計算するため、気をつける。
- 特に、地面や空は画面の中でかなりの面積をようするため軽めのShaderにすると良い。
Shaderについては各プラットフォームのprofilerで見た方がいい。
描画負荷を深掘りしたい場合
Unite2017 参加しました その6
C#ジョブシステムによるモバイルゲームのパフォーマンス向上テクニック
www.slideshare.net
はじめに
- これからの方向性を示した内容。まだまだ変わる可能性がある。
Jobs101
- マルチコアのハードにきちんと対応するためにJob化がされる。
- ただしマルチコアに対応するために並列処理をきちんと意識する必要がある。
- Unity2017.2 以降で対応予定
2017以降の新機能
- C++とC#間ではmarshalingなしでアクセスできるNativeArrayの型ができる
jobに最適化された新たなコンパイラができる
- jobSystemではGCが働かないunmanagedなので、developperがきちんとDisposeする必要がある。
- これにより、マルチスレッドにより特化したコーディングが可能となる。
MONOのコンパイル処理が変わる
- ILから中間言語を出して、最適化そしてLLVM送りさらに最適化、そしてメモリに書き込む。
現在のマルチスレッドに対する制限
- Jobをまだ止めることができない。
- スレッドセーフではない
job化のbest practice
DODへの方法
Step1(従来のMonoBehavior追加する方法)
MonoBehaviorに対して関数を追加して使う
Step2
オブジェクトのすべてのtransformをArrayで管理する。
Step3
IComponentDataを利用して、各Objectの情報を格納する
Step4
データの整合性をとれるようにする。
Unite2017 参加しました その5
シェーダープログラミング入門!カスタムシェーダー、作るで!
www.slideshare.net
rendering pipeline
どのようにして、Unityがレンダリングを実行するか
shaderを書くための言語
CG(C for Graphics) Sessionで使われてた言語はこれ。 C言語に似た言語
Shader Lab
CG(C for Graphics)の見方
v2f
v2fではvertexをCG(C for Graphics)で使えるようにするための構造体
Properties
Propertiesを利用することで、UnityのInspectorから値を指定することができる。 詳しくは参考URLのサンプルプログラムShader4
Shaderのタイプは大きく分け3つ
それぞれ表現方法によってどれを使うかは異なる。 基本的な使い方は、subshader の中にそれぞれに対応する関数を作ってあげる。
- Vertex Sharders
- Fragment Shaders
- Surface Shaders
Vertex Shaders
Vertex Shadersでは頂点を入力に対して、頂点を位置を変更して出力する。 Shaderで動きをつけたいときに使える。
flaot vert(appdata_base v)
頂点座標に対して処理を実行する
- 引数 appdata_base 頂点(vertex), 法線(normal), UV情報(texcorrd)が含まれている。 より詳細な情報(UV2)などは、appdata_fullという構造体に含まれている。
v.vertexに対して、倍率を指定すると拡大/縮小して表示することがができる。 時間などの係数をかけることで、簡単なモーションを表現することもできる。
Fragment Shaders
Pixcel 1つ1つに対して、色やAlpha値を変更するときに使える。 色彩の表現を付け加えるときに便利。
half4 frag(v2f i)
この関数のなかで各ピクセルに対して処理を実行することができる。
Sessionでは、この関数で以下を返すことで、Shaderが適応されたオブジェクト赤色になっていた。
return half4(1,0,0,1)
Surface Shaders
Pixel 1つ1つに対する処理というよりは、面に対して何かしらの表現を付け加えるときに便利。
void surf(Input IN, inout SurfaceOutput o)
事前にテクスチャをして置き、SurfaceOutputのalbedoを指定することでテクスチャを貼り付けることができる。
o.Albedo = tex2D(_MainTexture, IN.uv_MainTexture).rgb;
tex2Dの第二引数IN.uv_MainTextureでuv座標を指定しているため、第二引数を動的に変化させることでTexutureがオブジェクトの表面を流れるような表現をすることができる。
Emmission Texture
MainTextureが全体に対するベースとなるTexutureで、EmmissionTextureその上に張ることができる。Texutureを重ねて表現するときに便利
参考 その他テクスチャの張り方
事前にテクスチャを指定しておき、vert関数でuv座標を指定、fragでその色情報を取り出すことで、テクスチャの貼り付けができる。
参考資料
デモでかなりわかりやすく各Shaderを紹介していたので、動画が待ち望まれる!
Unite2017 参加しました その4
バグを殲滅!Unityにおける実践テスト手法
www.slideshare.net
Unity のテストツール
Unity 標準テスト環境あり
- Unity5.6 play mode
- Untiy5.5以前 edit mode
単体テスト
NUnit
- C#向けのテストツール
- Unityの古めのバージョンから支えていたが、Unity5.6からNUnit3系となったっぽい
TIPS
- MonoBehaiviorのオブジェクトはTearDownでnew する
- GUIで指定する各Objectは引数の差し替えで追加する。
- なので、依存関係がやばいとテストが大変
単体テスト環境の欠点
- MonoBehaiviorのライフサイクルはテストできない
- もしテストをするなら、MVPのPresenterのような形でライフサイクルときちんと切り出さなければならない?
- SingletonやStaticなものは、テストを再実行してもメモリ上に残る。(明示的にイニシャライザをしてあげる)
- Unity5.6未満だと、テストで作成されたgameObjectはテスト後でも残るので、明示的にデストラクタを呼ぶ必要がある。
結合テスト
方法
- キャラクタなどをnewして、Positionなどを整えることで結合テストが可能となる。
- Object間の関係をテストするのに使える。接触した場合の動作など。
- PlayModeであれば、ライフサイクルのテストも可能
MonobehaviourTest
- Unity5.6から使えるようになったテスト
- ライフサイクルをスタブする場合に便利かもしれない
- いくつかバグがすでに見つかっているので注意
その他 テストツール詳解
- UnityTestTools
- Integration Test Framework
- Unity UI Test Automation
Unite2017 参加しました その3
「黒騎士と白の魔王」にみるC#で統一したサーバー/クライアント開発と現実的なUniRx使いこなし術
www.slideshare.net
開発環境
- Perticleの関係で、IL2CPPでビルドはしているが、unity5.3.7
- MMORPG すべてのバトルはC#サーバーにて処理
- AI・演算・結果処理はサーバー
- クライアントはコマンドを受けて、画面を更新
C#大統一理論
メリット
- コードの共有が可能
- サーバーとクライアントのエンジニア同士が互いのコードを理解できる。
- サーバーとクライアントでエンジニアを入れ替えられる。(エンジニアのレベル向上)
- DLLなどの中間プロジェクトを共有できる
- SharedLibraryという中間定義をする必要があった
- IDL(Interface Definition Language)経由の中間コード生成が不要
デメリット
- エンジニアがサーバーとクライアントを合わせたチームになるため、コミュニケーションが困難
- エンジニアには得手不得手がある。
HTTP/2
WebAPIを置き換えるために何か別のフレームワークを利用したい
gRPCとは
- Googoleの提唱するHTTP/2のフレームワーク
- HTTP/2は常時接続・バイナリ通信をサポート
- gRPCはストリーミング通信をサポート
- Unityにおいて、リアルタイム通信が可能になる!
gRPCの導入
Battle Engine
- WebAPI系とリアルタイム通信系の2つ
- リアルタイム通信にはgRPCを使ったStreamingServerを実装
- ちなみに、敵のAI部分はF#で日本語プログラミング言語を実装
UniRX
- UniRXを利用して、MVVMのようなアーキテクチャを使っているようだ。
メリット
- 通信のハンドリングとRXの親和性は高め(非同期処理向け)
- Unity2017でasync/await が実装されるためこっちの方がオススメ
デメリット
- リアクティブスパゲッティが完成
- Rxと使いまくるとChaosへ。
- 伝搬を短くしましょう。
- 循環したらやばいので、注意する。
Tips
ToYieldInstructionの場合IObservableでEmpty返しても思い通りに動かない。 Neverを返すのがオススメ
その他
JSON.NET(Unity)のシリアライズ遅い
マスタデータの生成が遅い
- MasterMemory
- In memory databaseを利用することで解決