Unityが少し嫌いになった話

けちゃっぷ @kechako

kawasaki.rb

9年目突入 おめでとうございます🎉

Unity

  • Unity Technologies が開発・販売を行うゲームエンジン

  • クラスプラットフォームに対応している

    • iOS、Android、Windows、macOS、Linux、……

  • スクリプティングは C# を使用できる

私とUnity

  • 仕事で Unity を使ってアプリを開発している

千夏ちゃん

オペレーターがアバターになって客と会話する

アプリ構成

  • Coreパッケージ

  • Operator App

  • Customer App

これらを Unity で開発している

Core パッケージ

  • Operator App 及び Customer App の共通機能をパッケージとして提供

  • サーバーとの通信部分(gRPC、UDP)は Go で実装

  • 音声処理は libwebrtc の一部(AudioProcessor、Opus codec、Resampler)をネイティブライブラリ化

  • その他、共通のアセットなど

Operator App

  • iOS アプリ

  • 顔の動きをキャプチャーしてサーバーに送信

  • 音声の送受信

Customer App

  • Android アプリ

  • 音声の送受信

  • 顔の動きを受信して音声と同期して表示

  • カメラ映像をサーバーに送信

そしてそれは起きた

何が起きた?

  • Customer App が一定時間経過するとクラッシュする

  • Unity 内で例外が起こるとかではなく SIGSEGV で

  • クラッシュログの Backtrace が毎回違う?

原因は?

Out of Memory

  • 端末のメモリは 2GB(少なくね?)

  • メモリが半分くらいしか空いてない

  • アプリの使用メモリーが少しずつ増えている

  • 一定時間経過後 Out of Memory

メモリリーク?

  • リークするようなコードは見あたらない

  • しかし、アロケーションが頻発する雑なコード

  • Unity の GC が仕事をしていないようだ……

    (Unity の GC はメモリの移動は行なわないので、断片化によりヒープサイズが拡大し続けたりする)

対策

  • アロケーションを削減

  • 消費メモリーを削減

  • OS の空領域を増やす

アロケーションを削減

バッファをプールする
  • 音声とかカメラ映像とかのバッファーをプールし再利用する

クラスを使わないで構造体を使う
  • クラスはヒープに配置される = アロケーションが発生する

  • 構造体はスタックに配置される

クロージャできるだけ避ける
  • ラムダ式の中で外側の変数を使用するとキャプチャーされる

  • コンパイラーがクラスを生成するのでアロケートされる

ボックス化を避ける
  • 値型を object や interface などの参照型に代入すると、参照型に変換(ボックス化)される

  • ヒープに領域が確保され、スタックから値がコピーされる。

  • ジェネリクスに制約を付けて回避

    // Bad
    void Func(IInterface value) { }
    
    // Good
    void Func<T>(T value) where T : IInterface { }

消費メモリーを削減

  • アバターモデル(VRM)のテクスチャが無駄にでかかった

  • テクスチャを全体的に半分に

  • メモリ消費が200MBほど減った

OS の空領域を増やす

  • なにやらメモリを240MBほど消費しているサービスが

  • AirPlay や Chromecast のホストになるアプリがプリインストールされている

  • 不要なアプリは全て削除

これで解決!

それでも動作が不安定

  • かなり安定したが、それでもたまにクラッシュする

  • Unity IDE 上だとまったく問題無い

試行錯誤の結果

  • Android アプリのバックエンドを IL2CPP から Mono に変更

  • バックエンドが Mono だと、クラッシュしなくなった。

まとめ

  • C# 歴長いからって雑な書き方はあかん

  • Unity 向けの C# の書き方を

    • C# はコンパイラーがいろいろやらかすやってくれる

    • 普通に書けないのに C# である意味とは……

  • IL2CPP で安定しないのはよくわからん

  • Unity でゲーム開発者してる人達がんばってるなぁ