【Unity】tgz圧縮されたファイルをUnityPackageManagerで導入する時に発生するチーム開発ならではの問題と対策【チーム開発】

# TL;DR
- tarball 圧縮されたSDKをPackageManager経由で導入する際は、manifest.jsonを相対パスで記述しよう！！

# UPMをチーム開発で利用する時に起きる諸問題
UnityPackageManagerはnpm(Node.jsのパッケージ管理システム）の仕組みを利用したPackage管理システムです。

https://docs.unity3d.com/ja/2019.4/Manual/Packages.html

Githubで公開されているライブラリを導入できたり、Unity公式のパッケージではパッケージ間の依存性を解決して必要なものを一緒に導入してくれるなど、 `パッケージ(ライブラリ)管理の民主化` が一気に進んだ、待ちに待った！という機能です。

個人で開発する場合は特に問題ないのですが、小規模チーム開発や、企業で利用する場合は様々な観点で問題が発生します。

今回はその課題の一部とその対処法について紹介します。

## tarball で提供されているライブラリの導入方法
https://docs.unity3d.com/ja/2021.3/Manual/upm-ui-tarball.html

公式でも紹介されているとおり、ライブラリが重かったり、諸事情でOSSとして公開したくない場合は圧縮したファイルでパッケージを提供して、UPMとしてローカルファイルを取り込むことが可能です。(ローカルファイルはtarballで圧縮されています。)

このとき普通に導入するとPackageManager で導入したパッケージリストは ProjectRoot/Package/manifest.json というjsonファイルで管理されます。

ためしにARでUniTaskとUniRxを入れると以下のような感じでmanifestファイルが生成されると思います。

```manifest.json
{
  "dependencies": {
    "com.cysharp.unitask": "https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask",
    "com.google.ar.core.arfoundation.extensions": "https://github.com/google-ar/arcore-unity-extensions.git",
    "com.neuecc.unirx": "https://github.com/neuecc/UniRx.git?path=Assets/Plugins/UniRx/Scripts",
    "com.unity.collab-proxy": "1.17.7",
    "com.unity.ide.rider": "3.0.16",
    "com.unity.ide.visualstudio": "2.0.16",
    "com.unity.ide.vscode": "1.2.5",
    "com.unity.render-pipelines.universal": "12.1.8",
    "com.unity.test-framework": "1.1.31",
    "com.unity.textmeshpro": "3.0.6",
    "com.unity.timeline": "1.6.4",
    "com.unity.ugui": "1.0.0",
    "com.unity.xr.arcore": "4.2.7",
    "com.unity.xr.arkit": "4.2.7",
    "com.unity.modules.ai": "1.0.0",
    "com.unity.modules.androidjni": "1.0.0",
    "com.unity.modules.animation": "1.0.0",
    "com.unity.modules.assetbundle": "1.0.0",
    "com.unity.modules.audio": "1.0.0",
    "com.unity.modules.cloth": "1.0.0",
    "com.unity.modules.director": "1.0.0",
    "com.unity.modules.imageconversion": "1.0.0",
    "com.unity.modules.imgui": "1.0.0",
    "com.unity.modules.jsonserialize": "1.0.0",
    "com.unity.modules.particlesystem": "1.0.0",
    "com.unity.modules.physics": "1.0.0",
    "com.unity.modules.physics2d": "1.0.0",
    "com.unity.modules.screencapture": "1.0.0",
    "com.unity.modules.terrain": "1.0.0",
    "com.unity.modules.terrainphysics": "1.0.0",
    "com.unity.modules.tilemap": "1.0.0",
    "com.unity.modules.ui": "1.0.0",
    "com.unity.modules.uielements": "1.0.0",
    "com.unity.modules.umbra": "1.0.0",
    "com.unity.modules.unityanalytics": "1.0.0",
    "com.unity.modules.unitywebrequest": "1.0.0",
    "com.unity.modules.unitywebrequestassetbundle": "1.0.0",
    "com.unity.modules.unitywebrequestaudio": "1.0.0",
    "com.unity.modules.unitywebrequesttexture": "1.0.0",
    "com.unity.modules.unitywebrequestwww": "1.0.0",
    "com.unity.modules.vehicles": "1.0.0",
    "com.unity.modules.video": "1.0.0",
    "com.unity.modules.vr": "1.0.0",
    "com.unity.modules.wind": "1.0.0",
    "com.unity.modules.xr": "1.0.0"
  }
}
```

ここで PLATEU 等のtarballファイルを導入するとmanifestファイルは以下のようになります。
(PLATEU の導入は [公式マニュアル](https://project-plateau.github.io/PLATEAU-SDK-for-Unity/manual/Installation.html)   を参考にしてください )
```manifest.json

{
  "dependencies": {
    "com.cysharp.unitask": "https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask",
    "com.google.ar.core.arfoundation.extensions": "https://github.com/google-ar/arcore-unity-extensions.git",
    "com.neuecc.unirx": "https://github.com/neuecc/UniRx.git?path=Assets/Plugins/UniRx/Scripts",
    "com.synesthesias.plateau-unity-sdk": "file:/User/cova/UnityProject/DummyProject/Packages/SDKs/PLATEAU-SDK-for-Unity-v1.1.1.tgz",
    "com.unity.collab-proxy": "1.17.7",
    (中略)
    "com.unity.modules.xr": "1.0.0"
  }
}
```

このmanifestファイルをそのままGitでPush、チームに共有すると他の人は `100%UnityProjectでエラー` が発生し、導入に失敗します。

### 解決策

理由は単純で、tarballから導入するとデフォルトでは `絶対パス` で記載されます。
つまり、ユーザーが変われば `パスが存在しない` というふうに扱いされます。

そのため、 `導入したユーザーは動く` けど `それ以外のユーザーは導入失敗する` という不幸な事例が発生します。

解決策は単純で、導入者がちゃんと手動で `相対パスに書き換える` ことです。

先ほどのPLATEUのSDKは ProjectRoot/Package/SDKs/ 以下に配置していたので以下のように書き換えます。

```manifest.json

{
  "dependencies": {
    "com.cysharp.unitask": "https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask",
    "com.google.ar.core.arfoundation.extensions": "https://github.com/google-ar/arcore-unity-extensions.git",
    "com.neuecc.unirx": "https://github.com/neuecc/UniRx.git?path=Assets/Plugins/UniRx/Scripts",
    "com.synesthesias.plateau-unity-sdk": "file:./SDKs/PLATEAU-SDK-for-Unity-v1.1.1.tgz",
    "com.unity.collab-proxy": "1.17.7",
    (中略)
    "com.unity.modules.xr": "1.0.0"
  }
}
```

manifest ファイルがある ProjectRoot/Packages からの相対パスに変更することで、他ユーザーの人の導入に失敗しないようになります。

# まとめ
相対パス・絶対パス問題はチーム開発をした時に発覚しがちです。
個人開発では100％気付かないタイプの問題なので、チーム開発でtgzファイルでPacakgeを導入するときはmanifestファイルを相対パスに書き換えてからチームに共有しましょう！