太郎Work

Unityとかで困ったこと等を残しておきます

Unity2019時代のパッケージ管理

今までのUnityでは .unitypackage を使用したり Assets 以下にGitのSubmoduleで管理するといった方法がありましたが、やっとPackageManager周りが実用的になったので個人的に良いなと思ったフローを紹介します

今回の記事は2019.1.3で作成しています。今後仕様が変わる可能性があるので注意してください
ここで作成したサンプルはこちらに上げているので気になったらどうぞ
github.com


PackageManager

機能自体はUnity2018からありましたが最近自前でも追加できるようになったので今回はこのシステムを活用していきます
f:id:tarowork:20190518222834p:plain

パッケージ作成

プロジェクトにパッケージを登録するため、先に新規パッケージを作成します

最低限のファイル追加

早速パッケージに必要なファイルを作成します

f:id:tarowork:20190519014859p:plain
最低限追加したファイル構成

Documentation~

使い方を説明したファイルを格納するフォルダ
この名前にするとUnity上からは表示されず.metaも生成されない
Documentation~/index.mdを作成するとPackageManagerから開くことができる

Editor, Runtime

無理にここに作らなくてもいいがこの命名構成が公式に多い気がする
後述のAssemblyDefineの関係もありルートで分けておいたほうが吉

CHANGELOG.md

バージョンの変更点を記載したファイル
この名前にするとPackageManagerから開くことができる

LICENSE.md

適用ライセンスを記載したファイル
この名前にするとPackageManagerから開くことができる

package.json

まずはこれがないと始まらないです
jsonで記述するので以下のようにファイルを作成します

{
  "name": "custom-package-a",
  "version": "0.0.1",
  "displayName": "CustomPackageA",
  "unity": "2019.1",
  "description": "Custom package A",
  "dependencies": {
  }
}

ここは公式パッケージとフォーマットが同じなのでわかりやすいかと思います
※nameだけは小文字で記述する必要があります

AssemblyDefine追加

パッケージはAssets外に置かれるためC#ファイルはAssembly化されている必要があります。そのためRuntime、Editorフォルダ直下にAssemblyDefineファイルを作成し依存関係を設定します

f:id:tarowork:20190519021404p:plain
テスト用C#ファイルとAssemblyDefineファイル

特定パッケージに依存した時と切り分け処理を記述したい場合

f:id:tarowork:20190519025131p:plain
AssemblyDefine設定の一番下
パッケージを導入した状態であればResourcesから選択できるのでバージョン指定と任意の定義名を指定します

するとパッケージ内で以下のような切り分けが出来るようになります
”特定のバージョンのパッケージが入っていたら”等も出来ます
このサンプルではTextMeshProを参照していないので意味ないですが、切り分けられるイメージはつくと思います

public class LabelTest : MonoBehaviour
{
    [SerializeField]
    private UnityEngine.UI.Text _text;
    void Start()
    {
#if USING_TEXTMESHPRO_2_0_1
        _text.text = "TextMeshPro 2.0.1";
#elif USING_TEXTMESHPRO_2_0_0
        _text.text = "TextMeshPro 2.0.0";
#else
        _text.text = "uGUI Only";
#endif
    }
}

フォルダをアップロード

これらのファイルが用意できたらGithub等にアップロードします
扱いはフォルダでも大丈夫なので共有サーバーに上げるとかでも一応いけます
Gitリポジトリとして上げた場合は↓こんな感じになります
github.com

パッケージ登録

プロジェクトに先程作成したパッケージを登録します

パッケージ使用者が変更を加えずGitを使用する場合

Packages/manifest.json内のdependenciesに以下の1行を追加してプロジェクトを開くだけです
gitの権限は普段git cloneがうまく行っている環境であれば問題ありません

#0.0.2と指定している箇所はブランチ又はタグ名が使用できます

"custom-package-a": "https://github.com/tarob19/CustomPackageA.git#0.0.2"

Unityでインポートするとmanifest.jsonにlock項目が増えてました

{
  "dependencies": {
    "com.unity.package-manager-ui": "2.1.2",
    "com.unity.textmeshpro": "2.0.1",
    "custom-package-a": "https://github.com/tarob19/CustomPackageA.git#0.0.2",
    "com.unity.modules.imgui": "1.0.0",
    "com.unity.modules.ui": "1.0.0"
  },
  "lock": {
    "custom-package-a": {
      "hash": "8f0f898435924a969fff73f6f3455245fd07d1cd",
      "revision": "0.0.2"
    }
  }
}

プロジェクトから編集したい or フォルダで登録

個人的にはこっちのほうが編集しやすくてオススメです

SubmoduleをPackagesフォルダにクローン

バージョンの切り替えを容易にするため、プロジェクトにSubmoduleを追加します
クローン先はどこでもいいですがPackagesフォルダがおすすめです

f:id:tarowork:20190519001611p:plain
SourceTreeを使用した際のSubmodule登録画面

manifest.jsonにパッケージを登録

先程はGithubのアドレスを追加しましたがSubmodule(ディレクトリ)の場合はfile:を使用します(Packagesフォルダにクローンしていれば以下のようにシンプルになります)

{
  "dependencies": {
    "com.unity.package-manager-ui": "2.1.2",
    "com.unity.textmeshpro": "2.0.1",
    "custom-package-a": "file:CustomPackageA",
    "com.unity.modules.imgui": "1.0.0",
    "com.unity.modules.ui": "1.0.0"
  }
}

詳細な仕様は以下のスレッドで書かれています
https://forum.unity.com/threads/git-support-on-package-manager.573673/

PackageManagerで確認

ここまでの作業を行えばPackageManagerで確認が出来るようになります。

f:id:tarowork:20190519232532p:plain
PackageManager
パッケージ作成時にDocumentation~ファイル等を作成しているとPackageMangerの上部にあるリンクから直接飛ぶことが出来ます

まとめ

2019になってAssemblyDefineが強化されたので自作パッケージが実用的になりました
作成も楽なので自作ライブラリはパッケージ化していきたいですね