GitHubを使ったチーム開発

2022年1月13日

1つのプロジェクトでunityの共同開発を進める方法について基本の手順を考えます

目次

決め事

コーディングに入る前に、メンバー内で十分な意識合わせをしましょう

チーム開発のコツ

意識づけ

スケッチを含め、アイデア、企画、設計の途中の情報は記録するようにします。

プロジェクトの管理スタイル

管理の方法をメンバーで統一しておく事は大切です
メンバーみんなが扱えるように基本的な要素は、この資料で各自学習しておくようにしましょう。

開発スタイルは様々考案されていますが、比較的わかりやすく手順が簡略化されているものとして、GitHub考案のGitHubFlowという開発フローを採用するのがわかりやすいアプローチになるでしょう。

Unityプロジェクト特有のコツ

  • メインとなるSceneを更新するメンバーは1人にしましょう。(Sceneを更新する作業を同時に複数人で行うとどのSceneを採用するのか?難しい調整が必要になるため)
  • プロジェクトによっては、どうしてもシーンの作業を同時にしたいことがあります。その場合は、マルチシーンも検討しましょう
  • Prefabは、各自で作成し、他のメンバーとの依存性がないようにしましょう。(他のメンバーの更新によって動作しない、競合が発生するので)
  • 未使用のアセット、プラグイン、重複したライブラリをプロジェクトに残さないでください
  • 各自、担当(役割)を決めて、同時に同じファイルを更新しないようにしましょう
  • これらは、1つの作文用紙で2人交互に書いたり消したりする様子を思い浮かべると、あとでどうにかするにしても大変であることから、避ける方が賢明です。
  • ファイルの追加、削除、移動は、UnityのProjectビューで実行しましょう。エクスプローラで行うと、メタファイル(ファイルの情報についてUnity独自て記載されたファイル)との整合性が取れなくなります。(.metaファイルという隠し属性のファイル)
  • デフォルトのmainブランチは、常に動作可能なものにしておきましょう。ボーン(骨)となるところです。最悪、この状態まで戻すと稼働できるようにしておくようにしましょう。
  • Gitの仕様ですが、空のフォルダはリポジトリの対象になりません。ただし、メタファイル(ファイル情報を記載したファイル)は対象になります。

準備作業

運用に入るために開発環境を整えておきましょう
この準備は、一度だけ行えばいいです

インストール作業はプロジェクトごとには必要ないため、新しいプロジェクトの作成時はもっと簡単になります

必要な環境

バージョンの統一(各自)

Unityのバージョンを統一しておきます。

GitHub(クラウド)のユーザー登録(各自)

GitHubにサインアップしておきます。

UnityHubのIDを確認します。以降、このIDは必要になります。

GitHub Desktopのインストール(各自)

ローカル(PC)でバージョン管理を進めていくためのツールになります。GitHub社が提供しているので、親和性が非常に高く活発に開発を進められています。Gitは、高機能な仕組み(様々な修正、調整ができる)があるのですが、あえてリスクの高い作業(処理)は封印されています。このため、作業ミスによるコードのクラッシュを防ぐことができるようになっています。本来、プログラマが短時間で効率良くコーディングができるためのツールのはずなので、クラッシュを修正する時間が必要になる事はチーム全体としても非効率です。また、学習コストが高くなり習得に時間がかかることや慣れている人でもミスをすることもあることから、コンソールベースのコマンド作業は排除してもいいと思います。このツールがメジャーになるのはもう少しかかるかもしれませんが、ビジュアルツールを使う人口が多くなると、こちらがメジャーになっていくことでしょう。

Visual Studio Codeのインストール(各自)

コンフリクト(各自の更新内容が競合)の場合の処理が容易にできるためにエディターをインストールします。(GitHubDesktopと連携されているため使いやすいです)
コンフリクトの対応事例をこのページ内に記述していますので確認しておいてください

プロジェクトごとの作業

新規プロジェクトの作成(リーダー)

リーダーはチームで共有するリポジトリの元となるプロジェクトを作成します

GitHubDesktopでリポジトリ の作成(リーダー)

作成したプロジェクトフォルダをGitHubDesktopにドラッグアンドドロップしてリポジトリを作成します

メニューから作成する方法(参考)

GitHub(リモートリポジトリ)へ反映(リーダー)

作成したプロジェクトをGitHubへ Publish して リモートリポジトリを作成します

【有料機能】Github(リモートリポジトリ)で、mainブランチをプロテクトに設定する(リーダー)

(有料機能)安全のためmainブランチに直接コミットできないように保護します。
マージする場合は、プルリクエストで承認を必要とします

2020年10月1日から、GitHubでのデフォルトのブランチが[main]に変更されました。
これまで通りmasterを使うのかmainにするのかは決め事です

Setting メニュー

チームメンバーの参加登録(リーダー)

チームマンバーをプロジェクトに招待します

GitHub(クラウド)でチームメンバーをCollaboratorに登録する作業になります

Slack連携をする場合(リーダー)

作業ごとにSlackに作業内容が書き込まれるにすることができます

必要に応じて登録します

  • github連携(アプリ)のインストール
  • チーム開発チャネルを作成
  • /github subscribe owner/repo で、購読追加

プロジェクトのアクセス権の承認(メンバー)

登録されたメールアドレスにGitHubから承認メールが来ますので、「承認」のボタンをクリックします
これで、プライベートで作成されたGitHubリポジトリにアクセスできるようになります

プロジェクトをGitHub(クラウド)からPCへのコピー(メンバー)

Gitではリポジトリのクローン作成と呼びます

ファイルメニューのClone Repositoryを選択します

次のようにリポジトリが出てこない場合、承認(GitHub上)が未承認出ないかの確認、またはリロードしてみましょう

開発作業

GitHubでタスクの管理をします

ここからが日常のルーティーン作業です

リモートとローカルをうまく使ってチーム開発を効率よく進めるようにします
慣れてくれば、リモートワークのイメージを掴めると思います

Issue(問題・課題)を作成(リーダー・メンバー)

GitHubDesktopアプリメニュー

GitHubDesktopのファイルメニュー → Repository → Create Issue on GitHubを選択します
これは、リモートのGitHub上のIssueページへのリンクになります

GitHub側で、Issueを作成

上記選択で、GitHubへのインクへのジャンプ(ブラウザが起動)が行われます

Issueを作成し、Submit new issue をクリックします

自動採番されたIssue番号の確認

この場合、#7になりますね

ブランチを作成(割り当てられた担当者)

自分の環境でコーディングするため、ブランチを作成します

GitHubDesktopアプリメニュー

GitHubDesktopのファイルメニュー → Branch → New Branch…を選択します

ブランチ名を入力

選択したら、このようなウィンドウがポップアップ表示されますので、ブランチ名を入力して Create Branch をクリックします

GitHub(リモートリポジトリ)へ作成されたブランチを反映

作成されると、Publish branch(リモートのGitHubに書き出します)と表示されますので、クリックします。
GitHub上でもブランチが作成保存されます

コーディング(割り当てられた担当者)

準備が完了しました

ブランチ担当者は、コード作成、コミットを繰り返し作業を進めていきます。

mainブランチ(リモート)が別の担当者によって更新されたら必要に応じて作業ブランチにも取り込みます

コミットの書き方

次のようなプレフィックスをコミットの最初につけるとわかりやすくなります。

プレフィックス 機能新規機能追加詳細
add新規ファイルの追加
update修正仕様変更、バグ修正以外の機能追加、修正
fix修正バグの修正
remove削除削除、取り消し


さらに作業したIssue番号をつけます

サンプル

コードの更新箇所はGitを見ればわかるため、「Score変数を宣言した」など、コードの説明を書く必要はありません。
何をしたのか?なぜそうしたのかを書きます

Summary(概要説明)欄 必須Description(詳細説明)欄
[update] #7 スコアの表示機能を追加したプレイヤーのスコアを反映させた等
[fix] #7 スコアが増えない不具合を修正した当たり判定が検出されていなかったため等

GitHub(リモートリポジトリ)への反映

GitHubへPushして良いタイミングでPush origin(リモート側への更新)をクリックします
ブランチでの割り当てられた組み込みが終わるまでコーディング、コミット、Pushを繰り返します

コード作成完了時(割り当てられた担当者)

自分の担当が一通り完成し、Github(クラウド)上のmainブランチへ取り込みを依頼します
mainブランチは、いつでも動作可能な大切な状態なので、きちんと確認した上で作業を進めます

承認依頼(プルリクエスト:Pull Request)を作成します

GitHubDesktopでプルリクエスト(PullRequest)を作成します

プルリクエスト内容の入力

ブラウザがオープンし、Github(クラウド)の画面が表示されます

  • コメントタイトル
  • コメント内容(詳細)
  • レビューアー(プルリクエストを承認してもらうメンバー。複数でもOK)

を入力して、 Create pull request(プルリクエストの作成) をクリックします。

作成ボタンをクリックした後の画面

レビューが無いとのメッセージとマージがブロックされている旨のメッセージが表示されます
今の時点ではその通りなので承認を待ちます
掲示板のようなものも用意されており、コメントのやり取りができます(任意)

Github Desktopでも、プルリクエストの状態を確認することができます

承認、非承認の処理(承認者)

提出されたプルリクエストを確認し、承認、非承認の処理をします

プルリクエストの確認

Github(クラウド)のメニューで確認できます
Pull requestタブのカウンタが表示されているのを確認します
Pull requestsタブをクリックすると、確認、承認画面に切り替わります

検証作業

承認者は依頼のあったブランチの最新をGitHubDesktopでPullしてブランチを切り替え、動作をPCで確認します

レビュー

確認後、Add your reviewをクリックします

レビュー結果の選択

レビューの結果を選択します

  • Comment(コメント)
    明示的な承認をせずに、一般的なフィードバックを送信します。
  • Approve(承認する)
    フィードバックを送信し、これらの変更をマージすることを承認します。
  • Request changes(変更のリクエスト)
    マージする前に対処しなければならないフィードバックを提出してください。

Submit review をクリックすると画面が戻ります

承認処理

マージする場合は、Merge pull request を選択します。

マージ(merge)

再度確認画面が表示されるので、問題がなければ、Confirm merge(マージの確認) をクリックします

コンフリクト(コード内容が衝突している場合)が発生していると対応が必要になります

対応サンプル

承認ボタンをクリックして、対応済みブランチをmainブランチに結合します

ブランチを削除

対応済みブランチは不要なので削除します(事情により残す場合は除く)

承認者に承認・マージされた後の処理(割り当てられた担当者)

該当のローカルのブランチを削除します


ブランチは、割り当てられた処理を行うための枝になります。なので、作業が終了したら削除しておきます
削除したからといってプロジェクトに何か大きな影響があるわけではありません。作業の実態は既にmainに統合されています。
では、その作業が不備があり、続きをしたくなった場合どうすればいいのか?って心配になりますよね。
その場合は、また違うブランチを作ればいいです。前の作業からの違いが何かあるので再度作りたいと考えたでしょうから、それをブランチ名にしましょう。プロジェクトは個人の所有ではありません。自身が担当する作業が終わったら躊躇なく削除するようにすべきです。
もう一つの目的は、現在のブランチを見れば、並行してどの作業が進んでいるのかリアルタイムでわかることが挙げられます。既に完了済みの作業が残っていると、現在進められている作業を知りたくてもわからないのです。
あなたが、他のプロジェクトの応援をしたい時を考えてみるといいでしょう。メンバー1人ずつに訪ねて回りますか?次の日には変わっているかもしれませんし、メンバーの人数が2、3人とも限りません。
ただ、mainにマージされていないのに削除しないように注意しましょう

Delete…を選択すると、次の画面になります
リモートも削除をチェックするとリモート側のブランチも削除できます

削除したいブランチを選択した後、次の処理をします

プルリクエストを承認して、マージした後にブランチを削除する処理

mainブランチでfetchして更新分をPullします

fetch後、pullに表示が変わるので取り込んでおきます

以降、この一連の作業を繰り返します。

まとめると、次のようなルーティーンになります

  • Issue内容に沿ったブランチを作成
  • コーディング作業
  • タスクが完了したらプルリクエストを送る
  • mainにマージ
  • ブランチは削除

チームとして徹底することが重要です。mainが破壊されるのは防いでいますが、手順を抜くと後の処理が面倒になります。

プロジェクトが完成したら・・・

プロジェクトが一旦の完成を見たら、リリース作業を進めます
最初のバージョンは、v1.0がいいでしょう

実行可能ファイルの作成、リリース情報を作成、GitHubへのリリースまでで完成になります

GitHubを使ったリリース作業

バージョン番号の振り方

絶対ではありませんが、次のように採番するのがおすすめです

メジャー.マイナー.パッチ

それぞれの番号は半角ピリオドで区切られます。バージョン(番号)の上げ方は、要約するとこんな感じです。

リリース前のバージョンの場合

プレリリースバージョンは、パッチバージョンの直後にハイフンとドットで区切られた識別子を追加することで表現してもよいです(MAY)。識別子は必ずASCII英数字とハイフン [0-9A-Za-z-] でなければなりません(MUST)。識別子は空であってはなりません(MUST NOT)。数値の識別子はゼロから始めてはなりません(MUST NOT)。プレリリースバージョンは関連する通常のバージョンよりも低い優先度です。プレリリースバージョンは、不安定であり、関連する通常のバージョンが示す要件と互換性を満たさない可能性があります。

例:1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92。

0.xx.xx などの採番の方法もあります。チームで決め事として考えましょう。

参考

GitHubマニュアル(ドキュメント)

プルリクエスト(Pull Request)について

コミットが複数ある場合、1つにまとめる方法

コミットの履歴を綺麗にできます。プルリクエストに至るまでの個人メモ的な開発中のコミットメッセージがある場合、隠すことができます

マージはして欲しくないが、これでいいのかな?と確認して欲しい時。(有料バージョン:Pro,Team〜)

マージをしないプルリクエストを作成してマージ時の状態で確認だけして欲しいとき。コメントを欲しいとき。

プルリクエスト画面

GitHubDesktopでデフォルトのブランチ名を変更する方法(Version 2.5.6)

プロテクトされたブランチ(main)に単にpushした場合のエラー画面

GitHubDesktopで変更されたmainを自分のブランチに取り込む手順(各自)

Updateするコミットがない(mainとの差異がない)場合、このメニューはグレイアウトになり選択でできません。

競合が発生した場合

mainの取り込みをしばらく実行していない場合(mainのマージが進んでいる)、自分のブランチの変更箇所とmainの変更箇所が競合(同じファイルを変更している)する場合があります。慌てず、このページ下部の対応事例を参考に処理しましょう。

GitHubDesktopの開発コミット(実際の開発public)リポジトリになります。

素晴らしいアイディアやコードが形になる準備ができたらすぐに、コラボレーターとの会話をスタートするPull Requestを開ける機能

gitにおけるコミットログの書き方

gitにおけるコミットログ/メッセージ例文集100

チーム開発のコツ

役割の割り振り

Q. どうやってタスクを分業しているのか
  • 誰がどう実装しても同じような実装になる部分
    • 構造が決まっている構造体やクラスの定義
    • 設計済みのインタフェース定義
  • どんな実装であれ要件を満たすなら問題ない部分
    • プレイヤーの移動処理
    • オブジェクトの生成処理

こういう部分からまず分業して実装をしていきます。
逆に次のような部分は分業せず、誰か1人に任せたほうがいいです。

  • 多くのクラスを用いて処理を行う部分
    • ゲーム終了時に点数計算して表示する部分
    • シーンの初期化と終了部分

リアルタイムプロダクションサイクル

プロジェクトを進めるのには流れが必要です。開発の手順について学びましょう

開発のコツ

バグが少ない安定したゲームを構築するためのベストプラクティス
プロジェクトが大規模化してもコードを整然とした状態に保つコツ

Unityのフォルダ管理とGitHubの関係

空のフォルダとリポジトリの関係

Textフォルダ(ローカル)

Testフォルダを作成しただけでファイルは空の場合

GitHub(クラウド)リモートリポジトリ

Testフォルダが見当たりませんが、meteファイルだけ存在します

空でないフォルダとリポジトリの関係

Testフォルダ(ローカル)

Check.csファイルを追加

GitHub(クラウド)リモートリポジトリ

Testフォルダが作成されています

Github Desktopでのプルリクエストの確認方法

Github Desktopでも、次の操作で確認できます

Unity TechnologiesのGitHubリポジトリ

GitHub Flow

デフォルトのマスターブランチ名が変更されました

2020年10月1日から、GitHubでのデフォルトのブランチが[main]に変更されました。
これまで通りmasterを使うのかmainにするのかは決め事です

 GitHubの最高経営責任者(CEO)は、奴隷制度に関係する用語を不必要に使用するのを避けるために、「マスター」という用語を「メイン」などの中立的な用語に変更する取り組みを進めていることを明らかにした。

複数のシーンで作業がしたい

競合(コンフリクト)対応事例

mainを自分のブランチに取り込まずコーディングを進めていたが、そのままプルリクエストをしたことで、mainとの競合(相違)が発生した時の処理になります

GitHub側で処理が完結できる場合もありますが、競合箇所が多いとそのような自動的に競合を修復することができない時があります。
その場合、ローカル側でmainを取り込み、競合を処理してから再度Push,プルリクエストします

(ローカル)GitHub Desktopで処理

BranchメニューのUpdate from mainで、mainブランチを自分のブランチに取り込んだ場合、mainブランチの更新によっては、そのまま取り込めない状況が出てきます。その場合、競合が検出されますが、これを解決する手段がGUIで用意されていますので、活用します。

どちらかのファイルを選択することで対応ができる場合

同じファイルが存在しています。このままでは運用できないので使用したい方のファイルを選択する必要があります。

処理を中断したい場合、Abort Mergeを選択すると mainからの取り込みが中止されます

同一ファイルの内容を変更している場合

デフォルトのエディタ(Visual Studio Code)で対応します。

エディターで競合を処理

エディターで競合処理機能が備わっています。
選択したい方を考え、次のいずれかをクリックします。

  • 現在の変更を取り込む
  • 入力側(この場合、main)の変更を取り込む
  • 両方の変更を取り込む
  • 変更の比較(下図参照)

以上処理より、競合が全て解決されれば、PushやPullRequestが可能になります

変更の比較画面

Unityで座標での誤差程度の数値の違いでコンフリクトが発生した場合

意図していない(座標の移動を目的で作業をしていない)場合、main側を採用するようにしましょう
他のメンバーも同様にすることで、誤差が出たままの状態でのマージがなくなります

GitHubの便利機能

Issueごとに担当者を割り当てる

Issueを選択します

  • Assignees 担当者を割り当てる
  • Label どのような内容かをラベルづけする