やらなイカ?

たぶん、iOS/Androidアプリの開発・テスト関係。

Unityアプリを受託開発するときのライセンスとディレクトリ構成について

Unite Tokyo 2018のユニティ・テクノロジーズ・ジャパンさんブースで聞いたことのメモ。勘違いしていたので聞いてよかった。

受託開発の場合、受託開発する側は当然Unityライセンス必要として、顧客が納品されたアプリをApp Store等でリリースするケースで、顧客に何を買ってもらえばいいかの話。

Unityライセンス

原則は

「Unityライセンス(サブスクリプション)は、エディタを開いたりビルドしたりするのに必要」

とのことなので、

  • 受託側がビルドしたアプリを受け取って公開するだけなら、顧客(パブリッシャー)はUnityライセンス購入は不要
  • 受託側からソース(Unityプロジェクト一式)を受け取るとしても、Unityエディタで開いて検収・ビルドしないのであれば、Unityライセンス購入は不要
  • ソースをUnityエディタで開いて検収・ビルドする場合でも、エディタを使う期間だけサブスクリプションしていればよく*1サブスクリプションが切れてからもApp Storeに公開し続けて構わない

Asset Storeで購入したアセット

  • 納品物にソースとして購入したアセットを含めるのは再配布として扱う。再配布の扱いは各アセットのライセンスによる
  • 購入したアセットは除外して納品したとして、納品後、顧客側で個々のアセットを購入するタイミングでアセットがバージョンアップされている場合がある。Asset Storeから過去のバージョンのものはダウンロードできない点には注意

ディレクトリ構成の例

Asset Storeで購入したアセットを隔離する必要は感じていたので、以下のようにしています、という設定例です。以降はUnityさん推奨というわけではないのでご注意ください。また、後述しますが完全なものではないので、いいアイデアがあればぜひ教えてください!

Unityプロジェクトのディレクトリ構成

まず、プロジェクトのAssetsディレクトリ下に自社開発分を隔離するディレクトリを切ります(以下MY_PROJECT)。この下に、Editor, Prefabs, Scenes, Scripts, Tests*2など必要に応じて配置していきます。

Asset Storeや.unitypackageファイルをインポートしたものは、Assets/直下に配置ます。ディレクトリ名で別れてくれるものが大半ですが、EditorやPluginsの下に置かれるものもあるのでまとめて除外するためです。

.gitignore

.gitignoreファイルのベースを取得します。

$ curl -o .gitignore https://raw.githubusercontent.com/github/gitignore/master/Unity.gitignore

これに以下を追加します。

# PlayMode testing cache(たぶん)を除外
Assets/InitTestScene*.unity*

# 公開 or 納品するものであれば、自身のプロジェクト以外のAssetsを除外
/Assets/*
!/Assets/MY_PROJECT*

MY_PROJECTの後ろに/をつけてしまうと.metaファイルが漏れるので注意。

またもし、Assets/Editor/下やAssets/Plugins/下に置いているファイルがあれば、個別に除外指定(!ではじまる行)を追加してください。

課題

この方式では、以下の課題が未解決です。

  • リモートリポジトリをcloneしてそのままビルドできない。これはCI(continuous integration)を使用するときに致命的です。
  • Asset Storeからインポートしたアセットに独自の修正を加える場合。MY_PROJECT下に複製して修正するなどできますが、ライセンスを考えると問題ですし、差分に気づかない恐れもあります。
  • Assetの設定を自身のフォルダ下に格納するタイプの場合。EasySave2とか、Cross-platform Native Pluginsとか。これも差分に気づきにくいのがつらい。

このうちCIについては、開発機にあるフルセットのプロジェクトをUnity Collaborateに上げて、Unity Cloud Buildでビルドする方式を取っています。一人でやっているので大丈夫なのですが、チーム開発だと厳しい運用だと思います。

*1:とは言え最短1年ですが

*2:EditMode Testsだとprivateメソッドを直接呼べなくてストレスなのでPlayMode Testsを使っています