Unity reimport 差分警察24時

Unity reimport 差分警察24時

こんにちは。 Aiming ソフトウェアエンジニアの佐藤です。

みなさんは Unity で開発をしているとき、次のような経験はないでしょうか?

消しても消しても復活する meta の変更――
他人の変更を取り込んだらリロードする度に prefab に変更が出るように――

このような、 Unity で import を走らせる度に生まれる prefab, asset, meta などの変更(以後、まとめて「reimport 差分」とします)は、プロジェクトが大規模化するほど発生しやすくなります。
私たちのプロジェクトでも度々発生し、放置されて増え続けるなどの問題も起きていました。

本記事では、この課題に対して私たちのプロジェクトで取ったアプローチについて紹介します。
なお git の利用を前提としています。

h2. reimport 差分を放置すると何が起きるのか

そもそもなぜ放置して増え続けるのが問題なのでしょうか。

* 開発者によってゲームの状態が違う可能性がある
* Unity の import 時間が長くなる
* git add するときに選り分けるのが大変

開発時のストレスになるばかりでなく、特定しにくいバグを生む原因にもなり得ます。

h2. reimport 差分はなぜ生まれるのか

では発生の原因はなんでしょうか。いくつか考えられます。

* ローカルのキャッシュがおかしい
* commit し忘れ
* prefab の apply, scene の保存し忘れ

この中で最も厄介なのがキャッシュです。
これによって生まれる差分は難読で、どちらが正しいかぱっと見でわかりにくいことが多いです。

h2. reimport 差分が生まれないようにするには

そもそも reimport 差分が生まれるような変更が master に取り込まれなければ良いとすれば、 PR ごとに reimport all するテストを走らせてからマージすれば良いのです。

しかし reimport にかかる時間はプロジェクトが大きくなればなるほど長くなります。マシンスペックにも依存しますが、1時間以上かかるようなプロジェクトも多いでしょう。これをすべての PR でチェックするのはあまり現実的ではありません。

h2. reimport 差分にどう立ち向かうか

すべての PR でチェックするのが難しくても、定期的にチェックして通知しましょう、というのが私たちの落とし所になりました。

なぜそれで改善されたのかと、実装の詳細について説明します。

h3. どの状態が正しいのかわかるように

ローカルで発生している差分を、自信を持って PR に出し、安心してマージするためのコストが高かったのが放置され続ける原因のひとつでした。
今発生している差分は master に入れてもいいのか、確かめるために reimport にも時間がかかりました。

定期的に正しい状態を示すことで、発生している差分を PR に出しやすくなりました。

h3. 実装

Jenkins でシェルスクリプトを毎日深夜に実行し、 Slack にファイル名を書き込むようにしています。

#!/bin/bash

# Jenkins の git プラグインのオプションで実行しても良い
git clean -dfx

# 適当にプロジェクトを開いて閉じる
/Applications/Unity/Unity.app/Contents/MacOS/Unity -quit -batchmode -executeMethod "ReimportTest.EmptyMethod" -projectPath "${WORKSPACE}/client/"

status=`git status --porcelain`
echo "$status"
if [ -z "$status" ]; then
  echo "working tree is clean"
else
  echo "working tree is dirty"
  # ここで slack に投稿など
  exit 1
fi

import させるためだけに空のメソッドを定義したクラスを Editor ディレクトリ以下に作っておきます。

public class ReimportTest
{
    public static void EmptyMethod() { }
}

h2. おわりに

Unity で import を走らせる度に生まれる変更「reimport 差分」について、定期的にチェックし Slack に通知する方法を紹介しました。

この方法で、大量の差分が発生しているにもかかわらず、長期間放置されるようなことはなくなりました。
またエンジニア以外も通知を見て自分の作業範囲であれば積極的に修正をするようになり、コミュニケーションコストが削減されました。

もし同じような問題を抱えていれば、ぜひ試してみてください。