Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
#denatechcon
#denatechcon
Unity2018-2019を見据えた
DeNAのUnity開発のこれから
Haruto Otake
Group Manager
Gr 5, Game Development Infrastr...
#denatechcon
自己紹介
• 大竹 悠人(Haruto Otake)
• 開発基盤部 第五グループ 所属
• 来歴
• 2009/4 ドワンゴに新卒入社
• 幾つかのサービスや、家電/ゲーム機向けのプロダクトを担当
• 2013/5 ...
#denatechcon
アジェンダ
• Unityに今起きている事、我々がすべき事
• Unityの変化
• 我々がいますべきこと
• 具体的な活用例
• パッケージ管理
• 最速のアセットビルド環境の実現
• さいごに
#denatechcon
Unityに今起きている事、
我々がすべき事
#denatechcon
Unity、最近とてもいい感じじゃないですか?
• 明らかに機能の提供速度が上がっている
• 古くからの望まれていた課題が数多く解決に向かっている
• Nested Prefab, 2D Animation, Time...
#denatechcon
Unityの機能提供手法の変化
• Unity Package Manager (UPM)
• Unity 2018から実装された、npmベースのパッケージ管理システム
• manifest.jsonの記述に従って、E...
#denatechcon
これらの変化によって起きたこと
• Unity Editorの開発 != Unityの開発
• UPMのそれぞれのモジュールはUnity Editorの更新とほぼ独立して開
発が進む
• Unity Editorが更新...
#denatechcon
Unityの実装の方向性の変化
• 従来
• モノリシック
• 出来ることだけが出来る、ある程度の需要はそのままで実現できる
• 需要が出来ることを超えると拡張しづらい
• クローズド
• 実装の内部がかなり閉じられて...
#denatechcon
Unityの実装の方向性の変化
• 最近
• カスタマイズ性が重視されるようになり、モジュラリティが向上
• 拡張性のあるインターフェースが提供
• 複数のパッケージで多層的に機能を提供するような公式パッケージが増加
...
#denatechcon
車輪の再発明とミッシングリンクの補完
• 今までに提供していた機能ドメイン
• 単なる”機能の強化”ではない改善が増えた
• 捉え方を変えて車輪の再発明したり、オーバーホールして提供
• Nested Prefab, ...
#denatechcon
我々がすべきこと
#denatechcon
Unityだから…を言い訳にする時代の終わり
• 複雑な要求も正攻法で解決ができることが増加
• 回りくどい解決は回りくどい新たな問題を生む
• 正攻法で効率よく問題を解決できたほうが、ゲーム開発そのものに集
中できる
#denatechcon
我々がすべきこと
• 切り開けるようになった可能性を知る
• 単純に提供された機能だけでなく、何をカスタマイズできるように
なったかを知る
• UnityのアップデートだけでなくUPMパッケージの動向も気にする
• 可...
#denatechcon
具体的な活用例
#denatechcon
具体的な活用例
• パッケージ管理
• 最速のアセットビルド環境の実現
#denatechcon
パッケージ管理
#denatechcon
Unityの今までのパッケージ管理
• .unitypackage
• ファイルとメタ情報をセットにして1つのファイルにアーカイブし、それを
別のプロジェクトに取り込める機能
• GUIDをベースにして管理される
• ...
#denatechcon
DeNAの今までのパッケージ管理
• unitypackageはパッケージ管理とは呼べない
• 繰り返しになるが、そもそもそういう機能ではない
• パッケージ管理無しは耐えられない
• 正しくパッケージを更新できない
...
#denatechcon
なので
#denatechcon
DeNAの今までのパッケージ管理
• Upt (Unity advanced-Packaging Tool)
• パッケージ管理システムを内製
• 自治的な運用が可能であること
• 必要に応じてタイトルが自由に派生版や...
#denatechcon
DeNAの今までのパッケージ管理 – 構成
• .unitypackage生成時にmanifestファイルを同時に生成
• GUIDをmanifestに含んでおく
• 削除/更新時にこのGUIDを元に、プロジェクト内の...
#denatechcon
DeNAの今までのパッケージ管理 – 配布
• 中央サーバを置かない
• Github上のブランチをインポート時に指定する形式
• メジャーバージョンごとに開発ブランチを切ってモジュールを開発
• develop/v1...
#denatechcon
DeNAの今までのパッケージ管理
• Pros
• タイトル側で自由にforkして、1次対応やPull Requestを送れる
• GUIDで管理するので、安全なアップデートが可能
• 依存関係管理ができる
• Con...
#denatechcon
UptからUPMへ
• Unity Package Manager(UPM)が登場
• Uptを運用しなくてもいいのなら、その方向に寄せる
• インハウスでのパッケージ管理で必要なことを洗い直して、UPMへの
移行を検討
#denatechcon
インハウスでのパッケージ管理に必要なこと
• パッケージ管理システムとしての基本機能が動く
• パッケージを安全に導入/削除/更新できる
• パッケージ間の依存関係を設定できて、導入時に自動的に解決される
• 独自パッ...
#denatechcon
パッケージ管理システムとしての基本機能が動く
• 導入/削除/更新を安定して行えること
• UPMとそのベースであるnpmが安定すればそれでよい
• 現状若干UPMは不安定なところもあるが…
• エコシステムは独自であ...
#denatechcon
UPMでの独自パッケージ運用方法
• パッケージレジストリサーバーを立てる
• ローカルパッケージ運用
#denatechcon
独自UPMパッケージレジストリの構築
• Verdaccio
• npmレジストリサーバーのnode.js実装
• UPMはnpmベースなので、UPMレジストリサーバーとして運用可能
• UPMレジストリとして使う上で...
#denatechcon
独自UPMパッケージを作成する
• npmのようなpackage.jsonをルートに配置
• いくつか独自の属性がある
• https://docs.unity3d.com/Packages/com.unity.pac...
#denatechcon
Assembly Definition Files(asmdef)
• Scriptのコンパイル単位を分割する機能
• .asmdefファイルを置いたディレクトリ以下のスクリプトを1つの単位
にしてコンパイルする
• ...
#denatechcon
Asmdefのクラスプラットフォーム構成
• マクロ使えない問題
• asmdef内ではUNITY_IOSなどのプラッ
トフォーム識別マクロが働かない
• asmdefのインスペクタで代用
• 適用プラットフォームを選...
#denatechcon
独自UPMパッケージレジストリの利用
dependenciesの中に、利用するパッケージのパッケージ名を
キー名に、その値にバージョン名にして要素を追加する
registryキーとして
UPMパッケージレジストリのUR...
#denatechcon
パッケージのVendoring
• ローカル参照によるVendoring
• file:// スキーマでパッケージを展開したディレクトリへの相対パスをバー
ジョン名に記述して、特定のローカルパッケージをプロジェクト導入...
#denatechcon
DeNAでのUPMパッケージの開発時の構成
• 動作確認用Unityプロジェクト + パッケージ
• Packages以下に開発するパッケージを配置
• 動作確認用のUnityプロジェクトをImportTestとして配...
#denatechcon
これらの導入によって…
• より簡単に、より安全にバージョン管理のされた内製
パッケージをタイトルが導入可能になった
• 基盤開発だけでなく、タイトル側もUPMパッケージを
作ることで、モジュラリティを高めやすい構成に...
#denatechcon
具体的な活用例
• パッケージ管理
• 最速のアセットビルド環境の実現
#denatechcon
最速のアセットビルド環境の実現
#denatechcon
Unityのアセットビルド
• AssetBundleのビルドと利用は必須スキル
• Unityの鬼門とも言える存在
• 管理機構やローダを自作しないと動かせない
• 運用していくと、徐々にビルドが重くなっていく
• ...
#denatechcon
DeNAの今までのアセットビルド環境
• Unity4時代のものがベース
• 運用に入ると大きくは変えられない
• アセットバンドルがでかい
• 依存するアセットはすべて個々のアセットバンドルに巻き込む
• 依存関係を...
#denatechcon
既存システムの運用の結果として…
• 後付での高速化の為にフローが複雑に
• 手元でのビルドが性能と環境依存度の問題で困難になる
• ビルドサーバ(Jenkins)上で全員が手元で確認したい内容をビルド
• サーバに負...
#denatechcon
結構ダメダメだった
• 達成しなければならないこと
• 手元の小さな変化を手元環境でも高速にビルドでき、確認のイテレー
ションをすばやく回せること
• AssetBundle同士の依存関係を(柔軟に)設定/管理できるこ...
#denatechcon
SBP & RM & AAの登場
• Scriptable Build Pipeline(SBP)
• Player/AssetBundleのカスタム可能なビルドパイプライン
• Resource Manager
• ...
#denatechcon
Scriptable Build Pipeline
• Player/AssetBundleの従来のビルドパイプラインをオーバーホールして、
汎用的なビルドパイプライン構築フレームワークの上で再構成したもの
• Pro...
#denatechcon
Scriptable Build Pipelineの構成
• BuildTask
• ビルド処理の1ステップ。SBPでのビルドは登録したBuildTaskを順番
に実行する形で処理される
• ContextObject...
#denatechcon
AssetBundleビルドの中身
• 5フェイズで構成
1. セットアップ
2. スクリプトコンパイル
3. 依存性調査
4. パッキング
5. 書き出し
#denatechcon
重要なContextObject
• BundleBuildContent
• ビルド対象としてパイプラインに投げ込むアセットの構成
• どのアセットをどんな単位でAssetBundle化したいか
• AssetBun...
#denatechcon
Resource Manager
• リソースの場所と読み込む手段を定義するフレームワークと、その上で実
装されたAssetBundleを始めとした各種アセット読み込みの実装集
• Pros
• 読み込む手段を自分で定...
#denatechcon
Resource Managerの構成要素
• IResourceLocation
• リソースの識別子。ファイルパスと、自身を処理すべきProviderの識別子を持つ
• 自身の読み込みに必要なResouceLoca...
#denatechcon
主なResourceProviderの実装
• AssetBundleProvider
• ResourceLocationを元にAssetBundleをロードする
• BundledAssetProvider
• ロ...
#denatechcon
他の要素
• SceneProvider
• アセットでなく、Sceneの読み込み手段を提供するもの
• InstanceProvider
• インスタンスの生成手段を提供するもの
• 単なるInstantiateや、...
#denatechcon
Addressable Assets
アドレスという単位でアセットにアクセスする手段を提供する。Scriptable
Build PipelineとResource Managerをバックエンドとして利用し、ビルド
と...
#denatechcon
材料は出揃った!
#denatechcon
どう料理するか?
• これまで調査したことを元にした選択肢
• どれも使わない(以前のAPIを使う)
• Addressableを拡張して使う
• Resource Managerを使う
• Scriptable Bu...
#denatechcon
Addressableをそのまま利用できない理由
• 速度
• 上記のような構成の場合、規模が大きいプロジェクトで試すと最小の
変化でもビルドに10分かかることもある
• 手元でビルドするには困るオーダー
• 小回りの...
#denatechcon
Addressableはなぜ遅い? どうすれば速くなる?
• 最低所要時間がビルド対象のアセット総数に比例する
• ビルド対象のすべての依存関係を取得しないと、ビルドに必要な情報
を構築できない
• 依存性の検査やアセ...
#denatechcon
Addressableを改善/拡張しない理由
• やりたいことに対するギャップが大きい
• 速度面の改善のためにAddressableの枠組みを保たない、作り直しに
近い実装が必要
• やりたいことを実装として提供して...
#denatechcon
選択
• Addressableの役割をする層を、高速性にフォーカスして
再実装する
• SBPを直接使ってビルドパイプラインを構築
• RMを直接使ってAssetBundleを読み込む
#denatechcon
Abdool
(Asset Bundle builD tOOL)
#denatechcon
Abdoolの要件
• 高速である
• 手元の小さな変化を高速にビルドでき、確認のイテレーションをすば
やく回せること
• AssetBundleの構成を自由に構築できる
• 依存関係を設定し、ロード時に自動的に依存先...
#denatechcon
Abdoolのコアコンセプト
• 常に最速であり続ける
• 高速化は当然だが、モバイルゲーム運用においては速くあり続けるこ
とが難しい
• リリース直後は10分でビルドできても、1年運用したあとにその速度
を保つのは難...
#denatechcon
AssetBundleのビルドに必要な情報
• ビルドに投げ込むのは変更された物だけではない
• 同じAssetBundleに明示的に所属するアセット
• 同じAssetBundleから依存する別AssetBundle...
#denatechcon
前回ビルドから変更されたファイルの追跡
• Gitベースの変更ファイル追跡
• git statusとgit logを使って、最後にビルドしたリビジョン以降のファ
イルの変化をすべて列挙する
• ビルド時のアセット側の...
#denatechcon
依存性調査
• アセットの依存関係を高速に調査しビルド対象を決定する
• 変化したアセットから、依存関係の調査を行ってビルド対象を決定
• 常に最速であり続けるために、所属アセットバンドルの指定に制約を設ける
• 依存...
#denatechcon
所属AssetBundle構成ルールの制約
• 3つの制約を守って実装する
1. 間接的にAssetBundleに含まれるアセットの存在を許さない
2. あるアセットがどのAssetBundleに属するかは、そのファイ...
#denatechcon
AssetBundle構成の柔軟性の担保
• interface経由のAssetBundle構成ルール指定
• 柔軟性を高めるため、設定でなく実装として記述する
• どのアセットがどのAssetBundleに属するかを...
#denatechcon
インクリメンタルビルドの流れ
#denatechcon
アセット構成
#denatechcon
変更されたアセットを列挙
#denatechcon
変更されたアセットの所属するアセットバンドルを調査対象に
#denatechcon
変更のあったアセットの依存を辿る
#denatechcon
依存しているアセットの所属アセットバンドルをビルド対象に
#denatechcon
前回のビルド時に依存していたアセットバンドルもビル
ド対象に
#denatechcon
ビルド対象をSBPでビルド
#denatechcon
依存関係管理の難しさ
• Nested Prefab / Prefab Variantsという特例
• Nested PrefabはEditor内とビルド時で依存性が異なる
• Editorでは元Prefabを参照とし...
#denatechcon
Abdoolの戦略
• スクリプトキャッシュ
• 運用が進むにつれて、スクリプトコンパイル時間も増大しがち
• AssetBundleビルドには普通、コンパイルを必ず伴う
• コンパイル時間がビルド時間に影響し、ビルド...
#denatechcon
SBPを使ったカスタマイズ
• 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 Cache...
#denatechcon
Abdoolのロード戦略
• Resource Managerを全面的に利用
• ビルド時に生成したアセットリストや依存関係から、依存に沿った
ResourceLocationを生成
• CacheProviderを使...
#denatechcon
Abdoolを使ったロードのサンプル
• 構成
path/to/bundles
Catalog.bytes
(カタログ)
bundle1.unity3d
(アセットバンドル)
address/of/asset.png
...
#denatechcon
Streamを使った暗号化チャンクロード
• LoadFromStreamを使うと、StreamからAssetBundleを
読み込める
• ざっくりとした条件としては、シーク可能なStreamを与える必要がある
• ...
#denatechcon
最速のアセットビルド環境の実現
• “常に最速であり続ける”ビルド環境が構築できた
• Scriptable Build Pipelineを通してAssetBundleを深く理解すること
で、安全なインクリメンタルビル...
#denatechcon
他にもDeNAのUnity開発で取り組んでいること
• .NET 4.x
• Google公式のProtocolBuffersの採用
• gRPCの導入と開発ツールへの応用によるインタラクティブなデバッグ
• asyn...
#denatechcon
これからの展望
• Abdoolの改善
• 実機からの要求時にビルドするオンデマンドビルドサーバー
• アセットの所属AssetBundleを意識しない、高レベルのロードAPI
• UI Elements
• UI E...
#denatechcon
最後に
• Unityの変化をアンテナをより広げて、キャッチアップし
ていく覚悟を持たなければならない
• 開かれた可能性を咀嚼して、それを現実のプロダクトに実
利として反映しなければならない
• DeNAは覚悟を持っ...
#denatechcon
#denatechcon
Upcoming SlideShare
Loading in …5
×

Unity 2018-2019を見据えたDeNAのUnity開発のこれから [DeNA TechCon 2019]

13,189 views

Published on

DeNAではUnityを使って多くのゲームを開発していますが、Unityはいま、かつてない規模の大きな変革の時を迎えています。この大きなうねりのなかで、何が変わろうとしているかを知り、そして変化によって生まれる価値を正しく認識して開発に取り入れることができれば、Unityでのゲーム開発の効率を大きく改善させていくことができます。本セッションでは、Unityに今どのような改善がなされているのかについて話した上で、DeNAがその領域に対して今までどのように対処してきて、Unityの改善を受けてそれをどのように生かしてゲーム開発の現場に取り入れようとしているのかについてピックアップして説明していきます。

Published in: Technology
  • Be the first to comment

Unity 2018-2019を見据えたDeNAのUnity開発のこれから [DeNA TechCon 2019]

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

×