2024.12.10
“放置系”なのにサイバー攻撃を監視・検知、「統合ログ管理ツール」とは 最先端のログ管理体制を実現する方法
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.12.10
メールのラリー回数でわかる「評価されない人」の特徴 職場での評価を下げる行動5選
2024.12.09
国内の有名ホテルでは、マグロ丼がなんと1杯「24,000円」 「良いものをより安く」を追いすぎた日本にとって値上げが重要な理由
2024.11.29
「明日までにお願いできますか?」ちょっとカチンとくる一言 頭がいい人に見える上品な言い方に変えるコツ
2024.12.09
10点満点中7点の部下に言うべきこと 部下を育成できない上司の特徴トップ5
2024.12.04
いつも遅刻や自慢話…自分勝手な人にイラっとした時の切り返し 不平等な関係を打開する「相手の期待」を裏切る技
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.12.03
職場の同僚にイライラ…ストレスを最小限に抑える方法 臨床心理士が語る、「いい人でいなきゃ」と自分を追い込むタイプへの処方箋
2024.12.06
嫌いな相手の行動が気になって仕方ない… 臨床心理士が教える、人間関係のストレスを軽くする知恵
2024.12.05
「今日こそやろう」と決めたのに…自己嫌悪でイライラする日々を変えるには
PR | 2024.12.04
攻撃者はVPNを狙っている ゼロトラストならランサムウェア攻撃を防げる理由と仕組み