UnityでPull Requestベースで開発するとコンフリクト酷いよね問題

Unity(ここでは暗黙にUnity4のことを言う)でゲーム作ってます! GitとGitHubを使って開発できるようにはなった! ブランチ作って、Pull Request使って開発してます!

という場合でぶち当たる壁としてあるのは、壮絶なるコンフリクトとの戦い。

そのことについて、個人的にこうしてるよーというのを置いておく。 結論としては、「Unity4ではシーン上には何も置かないほうがいいと思う」であり、以下はなぜそう思うのかを、くどくど書いてある。

酔った勢いで公開しているので、あまりに真に受けられても困るというエクスキューズはある。

そもそも論

チームメイクで重要な事柄はいくつかあるが、製品のクオリティの担保や、組織の学習を維持すること、知識の属人化を防ぐことなどは特に重要な事項だ。 このために、中長期のプロジェクトは相互にレビューをするのが一般的であると思う。

こうした営みは、GitHubではPull Requestを使って行われる。

コンフリクト

通常、出したPull Requestが一瞬でマージされることはない。masterとPull Requestで出すブランチは次第に離れていく。

だから、編集頻度の高いファイルが存在すると、コンフリクト地獄へ突入する。Pull Requestは(原則小さくあるべきではあるが)ある一定のサイズで投げられる宿命にあるため、コンフリクトが発生する可能性が高いという面もある。

対策として、普通のプログラミングでは責務できっちり分割し、設計を上手く行うことなどが挙げられるだろう。が、Unityの場合はどんなにしっかり設計しようとも、シーンファイルがコンフリクトしてしまう。 シーンに配置したものは、どんなにprefabで分割しようと、シーンファイルに変更を及ぼしてしまう(ただしUnity 5で改善されるとか)。

コンフリクトを受け入れる

コンフリクトがある。どうするか。 当然、コンフリクトを受け入れ、シーンのマージを手動で行うという選択肢がある。

…あるにはあるが、実際にやったことのある方なら分かると思うが、かなりキツイ。修正が2, 3なら良いが、100近くなった日には涙がこぼれ落ちてしまう(100個の修正は普通にある)。 Pull Request単位なので時間の経過でmasterと全然違うことになっていたり、追加したファイルが多かった日には…。

masterを優先させるにしても、自分が入れていた値は全て飛んでしまうので、Pull Request1個分はさすがにきつい。 動作チェックをしてレビューも通っている状態になったのに、コンフリクト解消時に入れた値が間違っていたり、バグを埋め込んでしまうこともありえる。

特にコンフリクト解消時にエンバグしてしまうケースは、発見されないままになってしまう可能性が高く、危険である。 実際、コンフリクトを直した後に、直し方をミスったままリリースしてしまった、という例を見たことがある。

とにかく、コンフリクトを受け入れるという選択肢はない。可能な限り、コンフリクトを避けたい。

コンフリクトを避ける

有名なところだと、シーンを分割する方法があるようだが、この方法は実際のプロジェクト進行にマッチしない可能性がある。

実際のissue(BTSではチケット)はどういう単位で問題が切られるかと言うと、

  • キャラAを弱体化したい(HPを下げる)
  • 滑らかに移動したい(マップの凹凸を滑らかにする)
  • 武器Bの溜め状態を分かりやすくしたい(エフェクトを出す)

というような、価値や機能ベースでissueが切られる。 このような場合、位置でシーン分割をしても横断する可能性が高く、影響が複数シーンに渡ってしまう(と思う)。

よって、我々もユニティちゃんライブと同じように、シーン上には基本何も置いていない。

ただ、作っているのがそもそも敵をチマチマ配置するようなゲームではないので、シーン上に見えている必要性があまりないというのもある。

何も置かないケースの発展型として、メンバがそれぞれ作業用シーンを持つというパターンが考えられるが、こうした個々のメンバにメンテが任されるツールというのは、決まってメンテ不足なメンバが出てバグの温床になるので、採用しない方が良いと思う。

prefab単位のコンフリクト

prefab単位でコンフリクトするのはしょうがない。適切な大きさでprefabを分けているのであれば、十分解決できる範囲だというのが実感だ。

週に5〜15程度のPull Requestがmasterにマージされているが、そもそもコンフリクトはほぼ発生していないし、発生しても2, 3箇所直して終了することが多い。