2024.10.10
将来は卵1パックの価格が2倍に? 多くの日本人が知らない世界の新潮流、「動物福祉」とは
Unity Package Manager と Addressable Assets System を用いたプロジェクト分割について(全1記事)
リンクをコピー
記事をブックマーク
森哲哉氏:それでは「Unity Package ManagerとAddressable Assets Systemを用いたプロジェクト分割について」というタイトルで、キッズスター CTOの森哲哉がお話ししたいと思います。よろしくお願いします。
今日はこんな感じのアジェンダを用意しました。まずどんなことを話すかというところをザッと話して、本題をザッと話して、これをやるにあたっての注意点があるので、その辺も話してみようと思います。
さっそくLT(ライトニングトーク)の概要ですね。私は株式会社キッズスターでCTOをやっています、森と申します。美人の妻と、とってもかわいい娘5歳と、最近生まれたばかりの娘0歳9ヶ月に囲まれて暮らしています。Unity歴はだいたい8年目だと思います。TwitterやGitHubはこんな感じのアカウント(@monry)でやっていて、もんりぃ先生という名前で活動しています。
これは毎回言っているんですが、日本で唯一のMicrosoft MVP for Developer TechnologiesとUnity Ambassadorのダブルホルダーです。日本で唯一です。仕事は先ほども言いましたが、キッズスターというところで「ごっこランド」という、主に未就学児向のアプリをかれこれ7年くらい、けっこう長いことやっています。
このアプリがかなり好調で、今絶賛人を募集中です。このQRコードを読んで、ぜひ応募していただければなと思います。よろしくお願いします。今日のLTはUnity Learning Materialsで公開予定で、このあとアップロードしますのでお待ちください。
今日はAddressableについて、ちょっとマニアックな使い方を知りたいよという人、あるいはちょっとプロジェクトのサイズが膨れてきちゃってインポート時間がかかってしんどいんですという人、Addressableの深淵をチラッと覗いてみたい人などをターゲットに考えてスライドを作ってみました。
UPMとAASを用いたプロジェクト分割という、どこに需要があるんだかちょっと微妙なんですが、ひょっとしたら需要があるかもしれないネタについて話をして、基本的には、別のプロジェクトで作ったAddressableのCatalogを読み込んで、実際にアプリをビルドして動くようにするという話をします。
まだリリースはしていないんですが、実際に今これをやっていて、これをやるにあたっていろいろと課題も見えてきたので、その辺もちょっとお話ししようと思います。UPMやAASの細かい使い方は話しませんので、そのあたりはGoogleや過去に僕がしゃべったことなどを見てもらうといいかなと思います。
あとは、AASのCatalogの動的更新みたいなところは今回は触れないので、興味がある人はTwitterでメンションを飛ばしてもらえれば答えるかもしれません。ほかにも異常系の話も今回はしないので、そこはご注意ください。前置きは以上です。
では本題に入っていきたいなと思うんですが、プロジェクト分割についてです。実際に私が関わっている「ごっこランド」というプロダクトは、身も蓋もない言い方で言うと「キッザニア」のアプリ版と毎回呼んでいるんですが、今は確か41社、42社ぐらいの実在企業さんが、パビリオンというかたちで1つのアプリの中に出展しています。
各社、平均するとだいたい2個ぐらいミニゲームを展開しているので、60個以上のミニゲームが入っている、なかなかアグレッシブなアプリになっているんですね。そうすると、こんな感じのサイズになります。プロジェクトをduする(ファイル容量を確認する)と53ギガバイトという、スマホゲームにしてはわりと大きめのサイズです。
プロジェクトのサイズが上がるとどうなるのかというと、コンパイルやインポートの時間がメチャクチャ伸びるんですね。マジで長いです。その結果、生産性がめっちゃ下がります。実際に、1個のソースコードを1行直して、Unityにフォーカスを戻した場合、下手したら1分や2分かかることもありします。正直、マジで仕事にならないレベルなので、ちょっとこれはなんとかしなきゃいけないです。
じゃあどうやるんですか、何をやるんですかというと、うちではパビリオンごとにUnityのプロジェクトを分割して、40個のプロジェクトのスクリプトだけ母艦にマージして、リソースはAssetBundleでダウンロードしています。
その辺のプロジェクト分割をやっているんですが、これはもともと今日お話をする技術を使う前からやっていて、GitHubからプロジェクトを引っ張ってきて、そのプロジェクトを母艦で全部yarnでガチャンコして、ガチャンコしたやつをビルドサーバーががんばって1時間ぐらいかけてビルドしています。
AssetBundleはオレオレなAssetBundleManagerでダウンロードしていて、まだリリースはしていないので、現時点ではそういうかたちで動いています。AssetBundleのManagerもかなり継ぎはぎで作っていて、秘伝のタレがいい感じに煮詰められていて、ちょっとしんどい状態でもあるのが現状です。
それをどうやって使っていくのかですが、当然Addressable Assets Systemを使います。キーになるのはAddressableクラスの.LoadContentCatalogAsync()です。あとはUnity Package Managerでプロジェクトを同期する技術を使うことで、今まで弊社がやっていたことをそのままプロジェクト分割できるんじゃないかなと思います。
もう少し深掘りをしていくと、まずはAddressable Assets Systemですね。これは単純にそれぞれのミニゲームごとにプロジェクトを作り、AASをビルドします。ビルドすると、catalogというJSONファイルが作られるので、そのJSONファイルを母艦側で読み込むという、ただそれだけの話です。
今日このあとお話されると思いますが、neuecc(@neuecc)先生が作られたUniTaskが役に立っています。ありがとうございます。助かっています。これはUniTaskを入れておいて、UniTask.Addressablesを参照しておくと、そのままawaitできてとても便利です。
.LoadContentCatalogAsync()を叩くとresourceLocatorが返ってきます。resourceLocatorから何をどう引っ張ってくるかは自由ですが、resourceLocatorに含まれる全ロケーションをダウンロードするなど、こんな感じのコードを書くと一括ダウンロードできます。
AASの話はそんなに難しい話ではなくて、こう書けばその通り動くよねという感じですが、CatalogのURLですね。これはただの文字列なので、決定ロジックは若干気を遣う必要があります。ほかにも、実際に今どのバージョンを参照しようとしているのかを母艦側に何とかして伝えないと、アップデートがうまくいかないなどが起こり得ると思うので、その辺はちょっと注意が必要です。
ハッシュ値は、ビルド時に.hashというファイルで吐いてくれるので、この辺も使うといいと思います。AASの話はこんなところです。
もう1個のUnity Package Managerですね。こっちでC#のスクリプトを同期しないとダメです。ご存知のとおり、Unityの場合はビルドするプレイヤーにスクリプトを全部突っ込んでおかないと、基本的には動かないので、AASを作ったプロジェクトのそのソースコードだけはなんとかして母艦に持ってくる必要があります。
あとはIL2CPPのコードストリッピングによって、クラスやコンストラクタが落とされちゃったりするので、「これを落とさないでね」というlink.xmlの情報などを同時にもっておく必要があります。これをするにあたって、UPMのGit参照という機能がとても便利なんだろうなと思っています。
これはUniTaskとUniRxも一緒に書いてあるんですが、こんな感じのJSONファイルを書くと、Gitからプライベートでも取得できます。詳しくはスライドをご覧いただければなと思います。
ドキュメントには、パッケージ名をcom.始まりにしないとダメと書いてあって、嘘やんという感じなんですが、jp.co.でもいけたので大丈夫です。きちんとSSHなどの鍵を設定しておけば、プライベートリポジトリも参照できるのでそこは問題ないですね。
もう1つここを気をつけておくといいよというポイントは、母艦で必要ないものは.npmignoreを使って除外すると、チェックアウトにちょっと時間がかかっちゃうんですが、少なくともプロジェクトにはいらないファイルがコピーされないので、ちょっと軽くなって便利です。さっきも言ったんですが、link.xmlは除外しちゃダメです。
課題はシーンですね。AddressableのグループがLocalLoadPathから引っ張る場合に、プレイモードがFastModeになっているとうまく開けないことがあります。
EditorSceneManager.OpenScene()、要は編集モードで開こうとすると、パッケージに入ってくるソースコードは全部ReadOnlyになってしまうので、それが開けないとエラーで怒られるんですね。なので、UPMの仕様によってはLocalLoadPathで開こうとする場合にちょっと注意が必要になります。
SceneManagerの.LoadScene()や.LoadSceneAsync()で開く場合には問題ないのですが、たぶんZenjectなどを使っているとこれにハマるんじゃないかな思います。
ほかにも、Catalog URLの動的更新もRemote Settingsか何かを使えばいけるんじゃないかなと思っています。依存の依存にはSemVerしか使えないので、パッケージのURL、GitのURLを指定するのができないのも課題かなと思っています。
ご視聴ありがとうございました。
2024.11.13
週3日働いて年収2,000万稼ぐ元印刷屋のおじさん 好きなことだけして楽に稼ぐ3つのパターン
2024.11.11
自分の「本質的な才能」が見つかる一番簡単な質問 他者から「すごい」と思われても意外と気づかないのが才能
2024.11.13
“退職者が出た時の会社の対応”を従業員は見ている 離職防止策の前に見つめ直したい、部下との向き合い方
2024.11.12
自分の人生にプラスに働く「イライラ」は才能 自分の強みや才能につながる“良いイライラ”を見分けるポイント
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.11.11
気づいたら借金、倒産して身ぐるみを剥がされる経営者 起業に「立派な動機」を求められる恐ろしさ
2024.11.11
「退職代行」を使われた管理職の本音と葛藤 メディアで話題、利用者が右肩上がり…企業が置かれている現状とは
2024.11.18
20名の会社でGoogleの採用を真似するのはもったいない 人手不足の時代における「脱能力主義」のヒント
2024.11.12
先週まで元気だったのに、突然辞める「びっくり退職」 退職代行サービスの影響も?上司と部下の“すれ違い”が起きる原因
2024.11.14
よってたかってハイリスクのビジネスモデルに仕立て上げるステークホルダー 「社会的理由」が求められる時代の起業戦略