インディー開発者向けの開発事例です。Android版はベータリリース。iPhoneはEasyMobile対応待ち、Windowsは冬コミ向けです
開発環境
- unity2019.3.0f1(開発自体はb3から
- github private repository
- sourcetree
- dropbox
- jenkins
バージョン管理について
昔はさくらvpsにsubversionいれてましたが、githubの方が便利なので移行しました。
ただしファイルサイズ100mb制限があるのでそこだけ神経質になってます。alembicなどは簡単に大きくなるので尺を制限したり、30fpsにするなどで小さくします
dropboxはpsdやblendなどのグラフィック系の中間ファイルの簡易バージョン管理として使ってます。githubだとすぐにファイル制限にひっかかりますが、dropboxならその心配はありません。たまに上書きしてファイル台無しになったりしたので、バージョン管理しておいた方が安全です。
ブランチについて
develop一本にどんどんコミットしています。大きい破壊的仕様変更があった時は一時的にブランチ分けました。個人開発なので変にブランチ分けた運用はしないです。
グラッフィク仕様
モバイル版とデスクトップ版で一部のグラフィックリソースに違いがあります。
モバイル版
キャラクター 15000△までに抑える
敵 10000△までに抑える、少なければ少ないほどよい
- テクスチャは一律1k以下。
- ShaderはSimpleLitが基準
デスクトップ版
- 頂点数に制約無し
- LODは今のところ無し、負荷が厳しいようであればモバイル版をLowモデルとして使う
- テクスチャは2k以下
- ShaderはキャラのみリッチなLitベース
フォルダ構成
DropBox管理
Designer Planner
出力したpngやfbxやluaやjsonはrubyスクリプトでunity projectのAssetsに変更があった場合のみコピーします。
Git管理
Addressable Game MKFW(便利クラスまとめた自作フレームワーク 無数の外部アセット
失敗
外部アセットは自由に散らばせていたのですが無駄にHierarchyが長くなるので、せめてExternalAssets直下にまとめるなどしておけばよかったです。特にグラフィックやサウンド系はほぼ更新することはないので好き勝てに移動させてよいと思います。
Asset Import自動設定
Editor拡張でwindows, android, iphoneを設定するようにしmasita
。
windows開発機でエラー
しかしwindows開発機でiphoneの設定をしようとしたら、iphoneモジュールインストールしていないためエラーになった。そこでiphone設定部分だけ#if UNITY_IPHONEで囲いました。
全体設定の危険性
フォルダ指定ではなくプロジェクト全体で共通のテクスチャ設定にしていました。しかしそうするとPackageにあるtextureまで勝手に設定しました。必ず対象フォルダを設定しておくことをおすすめします(どうしても全体にするならせめてAssets文字が含まれているか判定しましょう
ローカライズ対応
unityにはpreviewですが一応ローカライズ機能あります。さすがにpreviewすぎるので使いませんでした。
自作のローカライズ系を使いました。
今回は、動的にフォントを切り替える方式を採用しました。各言語ごとにTextMeshProフォントアセット作りました。そして任意のタイミングでフォント(言語)を切り替えれるようにしました。しかし、この運用かなりめんどくさくて後悔してます。タイトルシーン以外での言語切り替え禁止方式にすればよかったです。
また言語ごとにTextmeshProフォントアセット作って都度読み込むのもめんどくさいです。全言語分ひとまとめにしてしまえばよかったです。googleが出してるNotoSansCJKであれば日本語、簡体字、繫体字、英語をサポートできるし、TextmeshProのfallbackを使えば追加で足せます。もちろんTMProの動的に文字追加するモードでの運用もアリです。
動的フォント切り替え方式のメリットとしてスクショ撮るときにフォントを一括で差し替えて全言語分のスクショを一度にとることができそう…なんですが、滅多に出番がないです。このためだけに動的フォント切り替えの仕組みでコード書くのはつらすぎます。
URP(Universal Rendering Pipeline
キャラクターだけSimpleLitにリムライトを追加した自作シェーダーです。それ以外は全てSimpleLitです。
最も基本的なメインカメラ一個、UIはUGUIのCamera overrideです
パフォーマンスを最適化するならUIはSpriteRendererベースがよいのですが、URPはカメラスタック未対応なので諦めました。
SRP Batcherを活かす
自作シェーダーもSRP Compatibleにしました。
今作は1マテリアル(1texture)、多数メッシュという背景づくりをしたため、かなり高速に描画できたんじゃないかなと思います。
キャラクターもたくさん表示されるのですが、SRP BatchがSkinningRendererにも対応したのでNPCの描画が効果的におこなわれています(学生が多くみんな制服という仕様も活きてます)。そのため当初予定していたMeshBakerによるNPCのメッシュ結合で1set pass目指すはやめました。
背景も考慮するとこのゲームはローポリゴンが超多いのですがBatchが効きまくるグラフィックリソースなのでさほど問題になりませんでした。
個人開発であまり最適化に時間とられるのもキツイので労せずパフォーマンス出る仕様が一番効きます
GPU Instancingは未使用
SRP Batchとの相性が悪いとのことでOFFにしました。Unity Blogにも書いてある通り、自動GPU instancing対応中とのことなのでそのうち自然にパフォーマンス上がりそうです。
Static batching, dynamic batching OFF
ロード時間が劇的に増えたり、SRP Batchrと相性悪いので無効化しました。
AssetStore素材
今回使ったアセットはURP未対応のアセット素材でした。
Edit>RenderPipeline>UniversalRenderingPipeline>Upgrade Selected Material to URP Material
これで変換することでURPで使えるようになりました。
しかし対応しているのがStandardshader→Litくらいでした。パーティクルは未対応だったので手動で変換しました
Addressable
エクスプローラー上はAddressable管理のリソースを全てAddressableというフォルダにまとめました。その中に色々なサブフォルダある感じです。
Residentは常駐用の一個の巨大なassetbundleです。フォルダを一個登録してあります。フォルダに新しいファイル追加しても自動的にaddressableに含まれるので楽です。
自動命名
今回はファイルたくさんではないのでAddressable Pathの自動設定系は使いませんでした。しかし衣装が増えてきそうなので自動登録できるようにしたくなってきました。
Shaderの重複
Unityのハマりどころです。今回URPのシェーダーはPackageの中にあります。PackageはAddressableの管理外のため何もしないと全てのAssetBundleにlit.shaderなどが含まれてしまいます。
SBPのCreateBuiltInShaderBundleを使う
ありがたいことにプロ技で解説ありましたね
//DefaultBuildTasks.Create(DefaultBuildTasks.Preset.AssetBundleCompatible);
var taskList = DefaultBuildTasks.Create(DefaultBuildTasks.Preset.AssetBundleBuiltInShaderExtraction);
こうするだけですね
間違いました。URP.Lit.shaderはbuild-in shaderではありません
そのため上記BuildInShaderのタスクは役に立ちません。ちなみに2019.4 VerifiedのAddressableであれば標準でBuildInShader.bundleを作っています。SBPの改造は必要ありません。
ShaderをAssetsに持ってくる
最も単純な対応です。今回はこっちにしました。(というよりSBPで用意されてるのに昨日まで気づきませんでした、後で変える予定です
ShaderVariantCollectionは使いませんでした
ShaderVariantCollectionは動的に発生するShader Compileによるカクツキを防止する手段です。今回はシェーダーの数が少なくカクツキも気にならないので使いませんでした。
無策にProject SettingsのGraphicsタブのSave to assetを使うと全shader varinatが参照されてしまい。巨大なアセットバンドルが生成されます。(僕の場合は20MB増えました。メモリに丸々のります。真面目にやるなら細かくShaderVarinatCollectionを分割します。
不要なリソースの削除
モバイルではリッチなデスクトップ版のリソースは必要ありません。デスクトップ版では体験版を作る必要があり要らないリソースがあります。またリリースではSRDebuggerは入れたくないです。今回は二種類の方法を組み合わせて対応しました。
ビルド前にファイルを直接削除
リリースビルドではruby scriptでSRDebuggerのフォルダを直接削除してます。これはjenkinsが行っています
SRPを改造しアセットを除く
オプションのクオリティ設定に応じてスケールかけるようにしました。一番修正工数が少ないからそうしたのですが、専用オプションでユーザーに設定させるでもよかったかなと思いました。
ポストプロセス
ON/OFFくらいは入れてもよかったかもしれないです
OcclusionCulling
学園内でオブジェクト数を大幅に減らせました。窓はもともと不透明なので学園内に入った時かなり効果的です
レイヤーカリング
机やいすなどの小物は壁に比べて早く消えてほしかったので専用レイヤーにし早めにカリングされるようにしました。効果的です