Skip to main content
#denatechcon
#denatechcon
Unity2018-2019を見据えた
DeNAのUnity開発のこれから
Haruto Otake
Group Manager
Gr 5, Game Development Infrastructure Dept.
Game Div, Game & Entertainment Business Unit.
#denatechcon
自己紹介
• 大竹 悠人(Haruto Otake)
• 開発基盤部 第五グループ 所属
• 来歴
• 2009/4 ドワンゴに新卒入社
• 幾つかのサービスや、家電/ゲーム機向けのプロダクトを担当
• 2013/5 DeNAに中途入社
• Webソーシャルゲームタイトルの運用ののち、新規ネイティブゲーム開発へ参加
• 基盤整備を得意としていたら、いつのまにかそちらが本業に
• 現在はUnityに関連した技術サポートと様々な内製ライブラリの制作に従事
#denatechcon
アジェンダ
• Unityに今起きている事、我々がすべき事
• Unityの変化
• 我々がいますべきこと
• 具体的な活用例
• パッケージ管理
• 最速のアセットビルド環境の実現
• さいごに
#denatechcon
Unityに今起きている事、
我々がすべき事
#denatechcon
Unity、最近とてもいい感じじゃないですか?
• 明らかに機能の提供速度が上がっている
• 古くからの望まれていた課題が数多く解決に向かっている
• Nested Prefab, 2D Animation, Timeline, Multiplayer, Rendering,
Scripting...
• リリースされたものがいい感じに使える
• これだよ! これ! 欲しかった物! という感覚
• なぜこう感じるのかを考えてみる
#denatechcon
Unityの機能提供手法の変化
• Unity Package Manager (UPM)
• Unity 2018から実装された、npmベースのパッケージ管理システム
• manifest.jsonの記述に従って、EditorがUnityのnpmレジストリから
パッケージをダウンロードして、プロジェクトに取り込む
• UPMパッケージの内容はプロジェクトディレクトリと分離されて管理される
• 簡単, 安全にパッケージの導入/削除/更新が可能になった
• バージョン毎に動作保証する
Unityバージョンが決まっている
#denatechcon
これらの変化によって起きたこと
• Unity Editorの開発 != Unityの開発
• UPMのそれぞれのモジュールはUnity Editorの更新とほぼ独立して開
発が進む
• Unity Editorが更新されなくても、UPMのモジュールの中で完結する
バグフィックスや機能追加はUPMでモジュールを更新することで恩恵
を受けることができるようになった
• Unityの従来の機能のうちの多くがUPMのモジュールに分割された
#denatechcon
Unityの実装の方向性の変化
• 従来
• モノリシック
• 出来ることだけが出来る、ある程度の需要はそのままで実現できる
• 需要が出来ることを超えると拡張しづらい
• クローズド
• 実装の内部がかなり閉じられていて、不具合を見つけてもヘルプデスク
経由で報告して修正されることを祈る & ワークアラウンドを積み重ねる
しかない
ナイーブな対応が要求される
#denatechcon
Unityの実装の方向性の変化
• 最近
• カスタマイズ性が重視されるようになり、モジュラリティが向上
• 拡張性のあるインターフェースが提供
• 複数のパッケージで多層的に機能を提供するような公式パッケージが増加
• モダン化/高速化
• C#のモダンな機能を使って実装されるようになり、APIの使い勝手が向上
• 高速な実装や、流儀に乗るだけで高速なコードを書ける枠組み
• オープン化
• 多くのパッケージがGithub上で公開され、開発にユーザーも参加可能
• Unity本体のC#ソースコードがUnityCsReferenceで公開
#denatechcon
車輪の再発明とミッシングリンクの補完
• 今までに提供していた機能ドメイン
• 単なる”機能の強化”ではない改善が増えた
• 捉え方を変えて車輪の再発明したり、オーバーホールして提供
• Nested Prefab, SBP, SRPなど…
• 今までに提供してこなかった機能ドメイン
• 有力なAssetStore上のアセットを買収した上でその機能ドメインを取
り入れるという流れも
• ProBuilder, Anima2D
#denatechcon
我々がすべきこと
#denatechcon
Unityだから…を言い訳にする時代の終わり
• 複雑な要求も正攻法で解決ができることが増加
• 回りくどい解決は回りくどい新たな問題を生む
• 正攻法で効率よく問題を解決できたほうが、ゲーム開発そのものに集
中できる
#denatechcon
我々がすべきこと
• 切り開けるようになった可能性を知る
• 単純に提供された機能だけでなく、何をカスタマイズできるように
なったかを知る
• UnityのアップデートだけでなくUPMパッケージの動向も気にする
• 可能性を検証し具体的な価値に転換させる
• 出来ることが増えても、活かさなければ宝の持ち腐れ
#denatechcon
具体的な活用例
#denatechcon
具体的な活用例
• パッケージ管理
• 最速のアセットビルド環境の実現
#denatechcon
パッケージ管理
#denatechcon
Unityの今までのパッケージ管理
• .unitypackage
• ファイルとメタ情報をセットにして1つのファイルにアーカイブし、それを
別のプロジェクトに取り込める機能
• GUIDをベースにして管理される
• Pros
• 手軽に作成できる
• Cons
• そもそもパッケージ管理システムではない
• アセットの更新がある場合、古いアセットが残ってしまう
#denatechcon
DeNAの今までのパッケージ管理
• unitypackageはパッケージ管理とは呼べない
• 繰り返しになるが、そもそもそういう機能ではない
• パッケージ管理無しは耐えられない
• 正しくパッケージを更新できない
• 内製SDKの更新時に古いファイルが残ったためにエラー発生
• 依存性管理ができない
• 既存の内製ライブラリ群がこれを理由に一つのリポジトリで管理
• なにか一つ更新するたびに、全体が更新されてしまう…
#denatechcon
なので
#denatechcon
DeNAの今までのパッケージ管理
• Upt (Unity advanced-Packaging Tool)
• パッケージ管理システムを内製
• 自治的な運用が可能であること
• 必要に応じてタイトルが自由に派生版やパッチを作り、導入できる
• 無くてもなんとかなる
• Uptを使わなくてもモジュールの導入自体は可能
• パッケージ管理システム自体の実装に時間を注がない
• 複雑で豪華なものを作ってもリスクが上がる
• 必要最低限のものをクイックに提供する
#denatechcon
DeNAの今までのパッケージ管理 – 構成
• .unitypackage生成時にmanifestファイルを同時に生成
• GUIDをmanifestに含んでおく
• 削除/更新時にこのGUIDを元に、プロジェクト内の旧アセットを一括削除すること
で、残すことがないようにする
• unitypackageをインポートすればモジュールは導入できる
.unitypackage manifest.xml
unitypackageの
相対パス
含まれるアセット
GUID一覧
パッケージ名 バージョン
依存パッケージの
リポジトリ,タグ
#denatechcon
DeNAの今までのパッケージ管理 – 配布
• 中央サーバを置かない
• Github上のブランチをインポート時に指定する形式
• メジャーバージョンごとに開発ブランチを切ってモジュールを開発
• develop/v1, develop/v2など
• 同じメジャーバージョンのブランチを常にimportすると最新の安全な変
更を取得できる
• manifestファイルに依存ライブラリが提供されているリポジトリを指
定する形で依存関係を設定する
#denatechcon
DeNAの今までのパッケージ管理
• Pros
• タイトル側で自由にforkして、1次対応やPull Requestを送れる
• GUIDで管理するので、安全なアップデートが可能
• 依存関係管理ができる
• Cons
• パッケージレジストリが存在しないため、パッケージを一覧できない
• DeNA独自である
• 利用される機会が限定されるのもあって、若干不安定
• 既存のエコシステムに乗ることができない。
• 独自であるが故に、利用側も概念を一定学ばなければならない
#denatechcon
UptからUPMへ
• Unity Package Manager(UPM)が登場
• Uptを運用しなくてもいいのなら、その方向に寄せる
• インハウスでのパッケージ管理で必要なことを洗い直して、UPMへの
移行を検討
#denatechcon
インハウスでのパッケージ管理に必要なこと
• パッケージ管理システムとしての基本機能が動く
• パッケージを安全に導入/削除/更新できる
• パッケージ間の依存関係を設定できて、導入時に自動的に解決される
• 独自パッケージを登録可能
• インハウスで使う以上は独自パッケージを登録できないと意味がない
• パッケージのvendoringが可能
• 中央サーバがシャットダウンしていても開発に影響がない
• 手元にある開発中のパッケージの動作確認が高速にできる
#denatechcon
パッケージ管理システムとしての基本機能が動く
• 導入/削除/更新を安定して行えること
• UPMとそのベースであるnpmが安定すればそれでよい
• 現状若干UPMは不安定なところもあるが…
• エコシステムは独自であればあるほど弱い
• エコシステムの中の豊富なツールチェインを活用できるようになる
• UPMというUnity標準
• npmというjavascript標準
• 例えば…
• “npm version”でのセマンティックなバージョン更新
• “npm-check-updates”での更新済みライブラリの検知と依存の更新
#denatechcon
UPMでの独自パッケージ運用方法
• パッケージレジストリサーバーを立てる
• ローカルパッケージ運用
#denatechcon
独自UPMパッケージレジストリの構築
• Verdaccio
• npmレジストリサーバーのnode.js実装
• UPMはnpmベースなので、UPMレジストリサーバーとして運用可能
• UPMレジストリとして使う上での注意
• UPMのEditor UIから未インストールの独自パッケージは閲覧できない
• インポートしたあとはリストに表示される
• Unity管理のモジュールについては、uplink機能でUnity公式のUPMレジストリに
リバースプロキシ接続させる必要がある
• UPMがPort80以外のポートに対応していないのでPort80でListenする
#denatechcon
独自UPMパッケージを作成する
• npmのようなpackage.jsonをルートに配置
• いくつか独自の属性がある
• https://docs.unity3d.com/Packages/com.unity.package-manager-
ui@1.8/manual/index.html#advanced-package-topics
• ルート以下のファイルがインポートされる
• スクリプトは何らかのAssembly Definition
Filesに属す必要
#denatechcon
Assembly Definition Files(asmdef)
• Scriptのコンパイル単位を分割する機能
• .asmdefファイルを置いたディレクトリ以下のスクリプトを1つの単位
にしてコンパイルする
• Asmdefからは、他のasmdefを参照関係に設定可能
• 参照関係を設定した場合、他のasmdef内のコードを参照可能
• asmdefの依存関係は、UPMの依存とは別
• Asmdefの依存と別に、UPM上の依存関係も組む必要がある
• 1つのUPMパッケージの中に複数のasmdefを含める事が可能
#denatechcon
Asmdefのクラスプラットフォーム構成
• マクロ使えない問題
• asmdef内ではUNITY_IOSなどのプラッ
トフォーム識別マクロが働かない
• asmdefのインスペクタで代用
• 適用プラットフォームを選択可能
• 除外された場合、依存していたとして
も無視される
• プラットフォームごとに別名をつけた
上で全てを参照
#denatechcon
独自UPMパッケージレジストリの利用
dependenciesの中に、利用するパッケージのパッケージ名を
キー名に、その値にバージョン名にして要素を追加する
registryキーとして
UPMパッケージレジストリのURLを記述する
Packages/manifest.jsonを編集
#denatechcon
パッケージのVendoring
• ローカル参照によるVendoring
• file:// スキーマでパッケージを展開したディレクトリへの相対パスをバー
ジョン名に記述して、特定のローカルパッケージをプロジェクト導入可能
• 依存しているものも自動でVendoringされるわけではない
• パッケージの取得
• UPMはnpmベースなので、npm用のツールチェインを活用できる
• yarnを使用
• yarn addで依存しているパッケージも含めて取得可能
• パッケージの展開先を指定可能
#denatechcon
DeNAでのUPMパッケージの開発時の構成
• 動作確認用Unityプロジェクト + パッケージ
• Packages以下に開発するパッケージを配置
• 動作確認用のUnityプロジェクトをImportTestとして配置
• パッケージをImportTestからローカル参照する
• この状態でImportTestを開くと、slnファイルが作られる
• ソースを直接編集でき、変更がUnity側ですぐにコンパイルされる
#denatechcon
これらの導入によって…
• より簡単に、より安全にバージョン管理のされた内製
パッケージをタイトルが導入可能になった
• 基盤開発だけでなく、タイトル側もUPMパッケージを
作ることで、モジュラリティを高めやすい構成になっ
た
#denatechcon
具体的な活用例
• パッケージ管理
• 最速のアセットビルド環境の実現
#denatechcon
最速のアセットビルド環境の実現
#denatechcon
Unityのアセットビルド
• AssetBundleのビルドと利用は必須スキル
• Unityの鬼門とも言える存在
• 管理機構やローダを自作しないと動かせない
• 運用していくと、徐々にビルドが重くなっていく
• 実装がブラックボックスになっているので内部を把握できない
#denatechcon
DeNAの今までのアセットビルド環境
• Unity4時代のものがベース
• 運用に入ると大きくは変えられない
• アセットバンドルがでかい
• 依存するアセットはすべて個々のアセットバンドルに巻き込む
• 依存関係を設定しない
• ビルドが遅い
• 依存関係が無いので、大量のリビルドが必要
• ビルド対象のハッシュを計算をしてビルドをスキップするが、最低必要時間
が長い
#denatechcon
既存システムの運用の結果として…
• 後付での高速化の為にフローが複雑に
• 手元でのビルドが性能と環境依存度の問題で困難になる
• ビルドサーバ(Jenkins)上で全員が手元で確認したい内容をビルド
• サーバに負荷が集中し開発規模をスケールする上でのボトルネック化
動作確認のイテレーションが回しにくく
#denatechcon
結構ダメダメだった
• 達成しなければならないこと
• 手元の小さな変化を手元環境でも高速にビルドでき、確認のイテレー
ションをすばやく回せること
• AssetBundle同士の依存関係を(柔軟に)設定/管理できること
• Unity側の大きな改修を控えていた
• 中途半端なものを作っても、速攻で新たなレガシーになりうる状況
#denatechcon
SBP & RM & AAの登場
• Scriptable Build Pipeline(SBP)
• Player/AssetBundleのカスタム可能なビルドパイプライン
• Resource Manager
• あらゆるリソースの管理者
• Addressable Assets
• SBPとRMを使って作られた、新たなAssetBundle管理システム
#denatechcon
Scriptable Build Pipeline
• Player/AssetBundleの従来のビルドパイプラインをオーバーホールして、
汎用的なビルドパイプライン構築フレームワークの上で再構成したもの
• Pros
• ブラックボックスが解消され、不具合を自力で追える
• 様々なカスタマイズが可能になった
• Cons
• 速度面で若干の無駄が残る実装
• ドキュメントが足らない
#denatechcon
Scriptable Build Pipelineの構成
• BuildTask
• ビルド処理の1ステップ。SBPでのビルドは登録したBuildTaskを順番
に実行する形で処理される
• ContextObject
• BuildTask間での値の受け渡しに使われるDIコンテナ兼パラメータ
• InjectContext属性をBuildTask内で使うと、依存性注入される
• ContentPipeline
• AssetBundleのビルドに必要なContextObjectをセットしたりしてくれ
るWrapper
#denatechcon
AssetBundleビルドの中身
• 5フェイズで構成
1. セットアップ
2. スクリプトコンパイル
3. 依存性調査
4. パッキング
5. 書き出し
#denatechcon
重要なContextObject
• BundleBuildContent
• ビルド対象としてパイプラインに投げ込むアセットの構成
• どのアセットをどんな単位でAssetBundle化したいか
• AssetBundleBuild構造体を元に生成される
• DependencyData
• BundleBuildContentを元に作られる、アセット間の依存情報
• サブアセットなどのアセットごとに含まれるオブジェクト情報
• アセットから依存しているオブジェクト情報
• BundleWriteData
• DependencyDataとBundleBuildContentから作られる、パッキング情報
• AssetBundleごとにどのアセットが含まれるかという情報
#denatechcon
Resource Manager
• リソースの場所と読み込む手段を定義するフレームワークと、その上で実
装されたAssetBundleを始めとした各種アセット読み込みの実装集
• Pros
• 読み込む手段を自分で定義して自由に追加でき、組み合わせることで、
複雑な振る舞いも簡単に定義できる
• リソースの場所の管理する層を読み込みロジックと分離できる
• Cons
• ドキュメントが足らない
• リソースの場所を管理する層は他に定義しないと、単体では使えない
#denatechcon
Resource Managerの構成要素
• IResourceLocation
• リソースの識別子。ファイルパスと、自身を処理すべきProviderの識別子を持つ
• 自身の読み込みに必要なResouceLocationを再帰的に複数保持できる
• IAsyncOperation<T>
• T型のリソースを読み込む非同期な操作を表す
• IResourceProvider
• ResourceLocationをもとにAsyncOperationを生成する、リソースの読み込み手段
• ResourceManager
• ResourceLocationを元にResourceProviderを決定し、リソース確保/開放処理を移譲
する
#denatechcon
主なResourceProviderの実装
• AssetBundleProvider
• ResourceLocationを元にAssetBundleをロードする
• BundledAssetProvider
• ロード済みのAssetBundleからAssetをロードする
• 依存するResourceLocationの結果からAssetBundleを取得する
• CachedProvider
• AsyncOperationの参照カウント付きキャッシュを行う
• キャッシュがなければ、指定されたProviderに処理を移譲する
#denatechcon
他の要素
• SceneProvider
• アセットでなく、Sceneの読み込み手段を提供するもの
• InstanceProvider
• インスタンスの生成手段を提供するもの
• 単なるInstantiateや、オブジェクトプールなど
#denatechcon
Addressable Assets
アドレスという単位でアセットにアクセスする手段を提供する。Scriptable
Build PipelineとResource Managerをバックエンドとして利用し、ビルド
と読み込みを行う。
• Pros
• 実装をすることなく利用可能で、多くの課題を解決できる
• Cons
• 速度面で問題を抱えている
• 設定の枠から出たことはやりづらい
#denatechcon
材料は出揃った!
#denatechcon
どう料理するか?
• これまで調査したことを元にした選択肢
• どれも使わない(以前のAPIを使う)
• Addressableを拡張して使う
• Resource Managerを使う
• Scriptable Build Pipelineを使う
• Scriptable Build Pipeline + Resource Managerを使う
Scriptable Build Pipeline +
Resrouce Managerを使うことに決定
#denatechcon
Addressableをそのまま利用できない理由
• 速度
• 上記のような構成の場合、規模が大きいプロジェクトで試すと最小の
変化でもビルドに10分かかることもある
• 手元でビルドするには困るオーダー
• 小回りの効かなさ
• パッキング単位を自由に調整したいが、グループ全体 or 1アセットの
単位でしかパッキングできない
• グループ毎にアセットを配置する必要があり、煩雑
• 設定ベースのカスタマイズ
• コンテキストが深く、設定を見てパッと何が起きるかを理解しづらい
#denatechcon
Addressableはなぜ遅い? どうすれば速くなる?
• 最低所要時間がビルド対象のアセット総数に比例する
• ビルド対象のすべての依存関係を取得しないと、ビルドに必要な情報
を構築できない
• 依存性の検査やアセットの実ビルドなど、コストが高い走査は結果を
キャッシュしてスキップするが、キャッシュ取得が遅い
ビルドに投げ込む必要のあるアセットの特定処理を、
最速であり続けるように実装する
#denatechcon
Addressableを改善/拡張しない理由
• やりたいことに対するギャップが大きい
• 速度面の改善のためにAddressableの枠組みを保たない、作り直しに
近い実装が必要
• やりたいことを実装として提供してくれているのは、SBPとRMの寄与
が大きい
• インターフェースが不安定かつ開かれていない
• まだ過渡期なのもあり、インターフェースの変化が多い
• 改変しやすい設計ではあるが、外から拡張が容易な作りではない
#denatechcon
選択
• Addressableの役割をする層を、高速性にフォーカスして
再実装する
• SBPを直接使ってビルドパイプラインを構築
• RMを直接使ってAssetBundleを読み込む
#denatechcon
Abdool
(Asset Bundle builD tOOL)
#denatechcon
Abdoolの要件
• 高速である
• 手元の小さな変化を高速にビルドでき、確認のイテレーションをすば
やく回せること
• AssetBundleの構成を自由に構築できる
• 依存関係を設定し、ロード時に自動的に依存先をロードする
• AssetBundle管理に必要な基本機能をきちんと揃える
• 柔軟に管理できること
• タイトル毎に取るべき構成は異なる
#denatechcon
Abdoolのコアコンセプト
• 常に最速であり続ける
• 高速化は当然だが、モバイルゲーム運用においては速くあり続けるこ
とが難しい
• リリース直後は10分でビルドできても、1年運用したあとにその速度
を保つのは難しい
• ビルド時間をプロジェクトのアセット総数に依存しなくして運用し続
けても速くあり続ける
• 変化したアセットの総量のみに依存してビルド時間が伸びるように
#denatechcon
AssetBundleのビルドに必要な情報
• ビルドに投げ込むのは変更された物だけではない
• 同じAssetBundleに明示的に所属するアセット
• 同じAssetBundleから依存する別AssetBundleに所属するアセット
• 依存する別のAssetBundleも同時にビルド対象に含めないと、依存性が設定され
ずアセットを二重に保持してしまう
依存関係を辿ってこれを特定する作業を
常に最速であり続けるように実現する
#denatechcon
前回ビルドから変更されたファイルの追跡
• Gitベースの変更ファイル追跡
• git statusとgit logを使って、最後にビルドしたリビジョン以降のファ
イルの変化をすべて列挙する
• ビルド時のアセット側のコミットハッシュをビルド結果に保存して、
git logの範囲を取る材料とする
#denatechcon
依存性調査
• アセットの依存関係を高速に調査しビルド対象を決定する
• 変化したアセットから、依存関係の調査を行ってビルド対象を決定
• 常に最速であり続けるために、所属アセットバンドルの指定に制約を設ける
• 依存対象のビルドのコストは、ビルド済みのものはSBPがキャッシュしてい
るため、枝切りをしている前提であれば無視できる
• 前回のビルド結果の利用
• アセットに変化がなければそのアセットからの依存も原則変化しないため、
以前のビルド時の依存関係をビルドに利用できる
#denatechcon
所属AssetBundle構成ルールの制約
• 3つの制約を守って実装する
1. 間接的にAssetBundleに含まれるアセットの存在を許さない
2. あるアセットがどのAssetBundleに属するかは、そのファイルパス情
報を材料として、他のファイルを走査することなく決定できる
3. AssetBundle名から、そのアセットバンドルに含まれるすべてのア
セットを、全体を走査することなく列挙できる
Assetの総数に影響されずに構成を決定できる
#denatechcon
AssetBundle構成の柔軟性の担保
• interface経由のAssetBundle構成ルール指定
• 柔軟性を高めるため、設定でなく実装として記述する
• どのアセットがどのAssetBundleに属するかを、特定のinterfaceを継
承したクラスを利用者側で実装して指定する
• 論理合成を可能にする
• 分岐やPrefix付与をするDecorator実装を完備
• 単純な構成であれば、標準の実装の組み合わせでカバーできるようにする
• 独自実装によって前述のルールを逸脱する危険性を下げる
#denatechcon
インクリメンタルビルドの流れ
#denatechcon
アセット構成
#denatechcon
変更されたアセットを列挙
#denatechcon
変更されたアセットの所属するアセットバンドルを調査対象に
#denatechcon
変更のあったアセットの依存を辿る
#denatechcon
依存しているアセットの所属アセットバンドルをビルド対象に
#denatechcon
前回のビルド時に依存していたアセットバンドルもビル
ド対象に
#denatechcon
ビルド対象をSBPでビルド
#denatechcon
依存関係管理の難しさ
• Nested Prefab / Prefab Variantsという特例
• Nested PrefabはEditor内とビルド時で依存性が異なる
• Editorでは元Prefabを参照として持つがビルドすると元Prefabの内容
が展開される
• AssetBundleとしては元Prefabへの依存を持たないが、ビルド時には
元Prefabが変化したときにビルドする必要がある
• Prefabの派生関係を抜き出してキャッシュ
• 派生元が変化した際に、派生先を全てビルドしなおす
#denatechcon
Abdoolの戦略
• スクリプトキャッシュ
• 運用が進むにつれて、スクリプトコンパイル時間も増大しがち
• AssetBundleビルドには普通、コンパイルを必ず伴う
• コンパイル時間がビルド時間に影響し、ビルドが早くなるほど支配的になる
• 手元でアセットの小さな変化を確認するときのスクリプトの変更は稀
• スキップできれば、時間あたりの試行回数をかなり担保できる
コミット毎にキャッシュを持つように
#denatechcon
SBPを使ったカスタマイズ
• AssetBundleビルドを伴わない、依存関係の調査のみを行
うパイプライン
• 一気に結果を取れて、個別にキャッシュされる
• 結果は内部構造らしさがあり、少々扱いづらい
• スクリプトコンパイルのスキップ
• ビルド後に得られるTypeDBのインスタンスをシリアライズしておき、次回の
同条件でのビルド時にデシリアライズ
• 循環参照の検出
• AssetBundle同士の依存が循環すると、利用自体は問題ないが整理が困難に
• 依存性検査の段階で低コストに検出する
#denatechcon
1アセット変化させた際のビルド時間
69
161
238 242
18
36
57
79
1 1 1 1
0
50
100
150
200
250
1000 2000 3000 4000
FullBuild Cached Build(Similer to Addressable) Incremental Build
バンドル数
ビルド時間(sec)
キャッシュビルド比 79倍
フルビルド比 242倍に!
#denatechcon
Abdoolのロード戦略
• Resource Managerを全面的に利用
• ビルド時に生成したアセットリストや依存関係から、依存に沿った
ResourceLocationを生成
• CacheProviderを使うと、これだけで参照カウント付きの実用的なAssetBundle
ロード機構を実現できる
• AssetBundleとアセットのそれぞれに用いるProviderを型パラメータとして指定
できるようなResourceLocationのファクトリを実装
• 幾つかのProviderを追加で実装
• 暗号化AssetBundle
• iOSのOndemand Resources(ODR)
#denatechcon
Abdoolを使ったロードのサンプル
• 構成
path/to/bundles
Catalog.bytes
(カタログ)
bundle1.unity3d
(アセットバンドル)
address/of/asset.png
(スプライト)
#denatechcon
Streamを使った暗号化チャンクロード
• LoadFromStreamを使うと、StreamからAssetBundleを
読み込める
• ざっくりとした条件としては、シーク可能なStreamを与える必要がある
• ランダムアクセス可能な暗号をStreamとして実装すること
で、暗号化されたAssetBundleをメモリに全展開すること
なく読める
• 大半の暗号化用Streamの実装はランダムアクセス不能なので注意
• AssetBundleのサイズが大きいと重くなるので、できるだけ小さくする
• アセットのサイズだけでなくAssetBundleサイズにも比例してしまう
#denatechcon
最速のアセットビルド環境の実現
• “常に最速であり続ける”ビルド環境が構築できた
• Scriptable Build Pipelineを通してAssetBundleを深く理解すること
で、安全なインクリメンタルビルドを実現する構想を得られた
• Unity標準の実装を活かしたアセットロード基盤を構築
• かなりのロバストネスを得ることができ、ランタイムで出来ることや
効率も以前より向上させることが出来た
#denatechcon
他にもDeNAのUnity開発で取り組んでいること
• .NET 4.x
• Google公式のProtocolBuffersの採用
• gRPCの導入と開発ツールへの応用によるインタラクティブなデバッグ
• async/awaitの導入とTask<T>の安全なハンドリングのノウハウ構築
• .NET Core SDKの導入
• .NET Core SDKを利用したUnityに依存しないUnity基盤開発体制
• Scriptable Render Pipelineの導入
• SRPによるモバイル向けのカスタムレンダーパイプラインの導入
#denatechcon
これからの展望
• Abdoolの改善
• 実機からの要求時にビルドするオンデマンドビルドサーバー
• アセットの所属AssetBundleを意識しない、高レベルのロードAPI
• UI Elements
• UI ElementsによるモダンなEditor UI開発の可能性を調査
• Prefab Improvements
• Nested / Variantを活かした効率的なUI実装とワークフローの検討
• ECS / C# Job System
• ECSとC# Job Systemの使い分けの模索とノウハウの積み上げ
#denatechcon
最後に
• Unityの変化をアンテナをより広げて、キャッチアップし
ていく覚悟を持たなければならない
• 開かれた可能性を咀嚼して、それを現実のプロダクトに実
利として反映しなければならない
• DeNAは覚悟を持ったUnityエンジニアを待っています
#denatechcon
#denatechcon