【Unity】GitHubを使ったチーム開発

2024年10月21日

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

目次

要約版

この資料は大きいです
要約版も用意していますので、全体を掴みたい方はそちらも参考にしてください

決め事

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

意識づけ

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

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

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

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

Unityの開発でgitコンフリクトが起こるケース

UnityでGitのコンフリクトが起こるケースは、特に複数の開発者が同じファイルやリソースを編集している場合に発生しやすいです。以下は主なコンフリクトの原因とその対処法です。

1. シーンファイルやPrefabファイルの編集

Unityのシーンファイル(.unityファイル)やPrefabファイル(.prefabファイル)はバイナリまたはYAML形式で保存されていますが、複雑な構造を持っているため、複数人が同時に編集するとコンフリクトが起こりやすいです。

  • 原因: 2人以上が同じシーンやPrefab内のオブジェクトを異なる方法で編集し、コミットした場合、マージ時に内容の衝突が発生します。
  • 対策: シーンやPrefabファイルの編集を担当者間で明確に分け、同じファイルを同時に編集しないようにする。また、ファイルをできるだけ細かく分割することで、コンフリクトのリスクを低減できます。

2. プロジェクト設定ファイル(.metaファイルやProjectSettingsディレクトリ)

Unityプロジェクトでは、各リソースに対して.metaファイルが生成され、これらにはファイルのGUIDやインポート設定が記録されています。さらに、ProjectSettingsディレクトリにはプロジェクト全体の設定が含まれています。

  • 原因: 複数の開発者が新しいリソースを追加したり、既存のリソースを変更すると、これらのファイルに変更が加わり、コンフリクトが発生することがあります。
  • 対策: メタデータファイルの競合を避けるため、可能な限り頻繁にプッシュとプルを行い、他の開発者との作業状況を同期させることが重要です。

3. バイナリファイル(画像、サウンド、モデルデータ)

Unityプロジェクトには、画像ファイル(PNG、JPEG)、サウンドファイル(WAV、MP3)、モデルファイル(FBXなど)が含まれており、これらのバイナリファイルがGitでコンフリクトを起こすこともあります。

  • 原因: バイナリファイルはGitで簡単にマージできないため、同じファイルが別々に編集されるとコンフリクトが発生します。
  • 対策: バイナリファイルはできるだけ一人の担当者が編集するようにし、変更をプッシュする前に他の変更をプルして衝突を回避する。また、Git Large File Storage(LFS)を使用してバイナリファイルを管理するのも有効です。

4. .gitignoreの設定不足

Unity特有のファイル(LibraryフォルダやTempフォルダなど)をGitで追跡しないようにするため、.gitignoreファイルを正しく設定する必要があります。

  • 原因.gitignoreファイルが適切に設定されていない場合、Unityが自動的に生成する一時ファイルがGitで管理され、不要なコンフリクトが発生することがあります。
  • 対策: Unity専用の.gitignoreテンプレートを使用して、不要なファイルがGitに含まれないように設定する。

5. テキストファイルの行末コードの違い

複数のプラットフォーム(Windows、macOS、Linux)で開発している場合、テキストファイルの行末コード(CRLFやLF)が異なるため、意図しない変更が発生し、コンフリクトの原因となることがあります。

  • 原因: プラットフォーム間で異なる行末コードが適用され、ファイルの内容が変わったと認識される。
  • 対策.gitattributesファイルを使用して、テキストファイルの行末コードを統一する設定を行う。

まとめ

UnityプロジェクトでのGitコンフリクトを避けるためには、ファイルの編集権限をチーム内で明確に分け、頻繁なコミットとプルで他の開発者との同期を保つことが重要です。また、必要に応じて.gitignore.gitattributesの設定を適切に行い、ファイルの競合を防ぐ工夫が必要です。

準備作業

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

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

必要な環境

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

  • UnityEngineのバージョンを統一しておきます
  • Unityエディターで使われるPackageを統一しておきます(PackageManagerでバージョンを確認)
  • VisualStudio等エディタのバージョンを統一しておきます

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

  • GitHubにサインアップしておきます。
  • UnityHubのアカウントを確認します。以降、このアカウントは必要になります。

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

  • ローカル(PC)でバージョン管理を進めていくためのツールになります。
  • GitHub社が提供しているので、親和性が非常に高く、活発に開発を進められています。
Git管理ビジュアルツールについて

このツールはローカルPCでのバージョン管理を行うためのもので、GitHub社が提供しているため親和性が高く、活発に開発されています。Gitは高機能で様々な修正や調整が可能ですが、リスクの高い処理はあえて封印されており、作業ミスによるコードのクラッシュを防ぎます。プログラマが効率良くコーディングできるよう、クラッシュ修正に時間を割くのはチーム全体で非効率です。また、学習コストが高く慣れた人でもミスをする可能性があるため、コンソールベースのコマンド操作は排除しても良いでしょう。ビジュアルツールの利用者が増えれば、このツールもいずれメジャーになると考えられます。

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

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

Gitのインストール(各自)

  • ここは、すでにインストール済みであればパスして構いませんコンフリクト(各自の更新内容が競合)の処理を行うために必要になります
  • コンフリクトの対応事例をこのページ内に記述していますので確認しておいてください
  • 最新版をインストールします
    • ダウンロード、インストールを進めます
    • インストーラーで確認画面がいくつか表示されますが、基本、デフォルトで進めてもらっていいです

プロジェクトごとの作業

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

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

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

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

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

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

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

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

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

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

Setting メニュー

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

チームメンバーをプロジェクトに招待します(コラボへ登録)

GitHub(クラウド)でチームメンバーをCollaboratorに登録する作業になります
手順の通りに選択していきます

③をクリックすると、ウィンドウが開きますので、参加させるアカウントを入力し、緑のボタン(Select a collaborator above)をクリックします
人数分、繰り返します

Slack連携をする場合(リーダー):オプション

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

必要に応じて登録します

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

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

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

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

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

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

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

開発作業

ここからが日常のルーティーン作業です。リモートとローカルをうまく使ってチーム開発を効率よく進めるようにします。

Projects(GitHubの機能)を使った進捗管理

リンクを参考に試してみましょう

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

GitHubDesktopアプリメニュー

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

GitHub側で、Issueを作成

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

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

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

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

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

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

  1. GitHub DesktopのメニューからBranch → New Branch...を選択。
  2. ブランチ名を入力してCreate Branchをクリック。
  3. Publish branchをクリックしてリモートにもブランチを作成。

GitHubDesktopアプリメニュー

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

ブランチ名を入力

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

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

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

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

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

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

コミットの書き方

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

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


Issue番号をメッセージの前につけます

例:

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

[update] #7 スコアの表示機能を追加したプレイヤーのスコアを反映させた等
[fix] #7 スコアが増えない不具合を修正した当たり判定が検出されていなかったため等

Summary(概要説明)欄には、概要を追記しましょう

GitHub(リモートリポジトリ)への反映:オプション

Pushのタイミング

一定のまとまった作業を完了して時点で構いません
Push originを実行するとリモートに反映されますので、PC上でのUndoのやり直しは不可になります

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

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

自分の担当が一通り完成し、GitHub上のmainブランチへ取り込みを依頼します。

  1. レビューアーを指定してCreate pull requestをクリック。
  2. プルリクエスト(Pull Request)を作成します。
  3. GitHub Desktopでプルリクエストを作成し、ブラウザで詳細を入力。

承認依頼(プルリクエスト: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 に統合されています。

では、その作業に不備があり、続きをしたくなった場合はどうすればよいのでしょうか。心配になるかもしれませんね。

その場合は、また新しいブランチを作ればよいのです。前の作業との違いがあるので再度作業したいと考えるでしょうから、その内容をブランチ名にしましょう。プロジェクトは個人の所有物ではありません。自身が担当する作業が終わったら、躊躇なく削除するようにすべきです。

もう一つの利点として、現在のブランチを見ることで、どの作業が並行して進められているかをリアルタイムで把握できる点が挙げられます。既に完了した作業が残っていると、現在進められている作業を知りたくてもわからないのです。

あなたが他のプロジェクトを手伝いたいと考える場合を想像してみてください。メンバー一人一人に尋ねて回りますか。次の日には状況が変わっているかもしれませんし、メンバーの人数も 2、3 人とは限りません。

ただし、main にマージされていないブランチを削除しないように注意しましょう。

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

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

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

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

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

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

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

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

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

プロジェクトが一旦の完成を見たら、リリース作業を進めます

GitHubを使ったリリース作業

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

Unityアプリを参考に具体的なリリース作業についてリンクを確認しておきましょう

バージョン番号の振り方

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

最初のバージョンは、v1.0がいいでしょう

メジャー.マイナー.パッチ
メジャー(ビリオド)マイナー(ピリオド)パッチ

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

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

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

https://semver.org/lang/ja/

例: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 を自分のブランチに取り込まずにコーディングを進め、そのままプルリクエストを行ったため、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 どのような内容かをラベルづけする