【Unity 6】GitHub Desktopで始めるチーム開発入門|2人でコイン収集ゲームを完成させよう

広告

Unityで一人のゲームを作れたら、次は二人で作ってみましょう。ただし、同じフォルダーを共有するだけではチーム開発になりません。「自分の作業を相手に渡す」「相手の変更を確認して取り込む」「完成したものを二人とも再現する」という手順が必要です。

このチュートリアルでは Unity 6+GitHub Desktop+GitHub を使い、プレイヤー移動とコイン収集を分担します。最終的に、一つのシーンでプレイヤーが移動してコインを3個拾い、「クリア!」と表示できれば成功です。Git操作に集中できるよう、ゲームの仕様は意図的に小さくしています。

今回のゴールと役割分担

担当作るもの編集する主なファイル
Aさん四方向に動く青いPlayerPlayerMovement.cs、Player.prefab
Bさん触れると消える黄色のCoin、スコア表示Coin.cs、CoinCounter.cs、Coin.prefab、CoinCounter.prefab
2人で確認Pull Request、マージ、最終シーンで動作確認MainScene.unityは統合時にAさんだけが編集

重要な約束: それぞれの機能をPrefabにしておき、開発中は二人とも同じシーンを編集しません。UnityのシーンやPrefabはテキスト形式で保存できても、同じ箇所を同時編集すると競合が起こりえます。今回は競合を減らす構成から学びます。

STEP 0:事前準備

  • 2人とも 同じUnity 6のEditorバージョン をUnity Hubからインストールする(例:両者が同じ6000.x.y)。
  • GitHubアカウントを用意してGitHub Desktopへサインインする。
  • UnityでC#スクリプトを開けるエディターを準備する。
  • この教材では Input System を使用します。Unity 6.6の新規プロジェクトでは標準で有効なので、追加の設定は必要ありません。

※ 画面項目はUnity 6のマイナーバージョンで異なる場合があります。この教材のコードは Input System の Keyboard.current を使うため、旧Input Manager専用の設定では実行できません。キーを押しても動かないときは、Edit > Project Settings > Player > Active Input Handling が Input System Package (New) または Both になっているか確認し、変更を求められたらEditorを再起動してください。

STEP 1:Aさんが最初のUnityプロジェクトを作る

  1. Unity Hubで 2Dテンプレート のプロジェクト CoinCollectorTeam を作成します。
  2. Unityでシーンを Assets/Scenes/MainScene.unity として保存します。
  3. Projectウィンドウで Assets/Scripts、Assets/Prefabs、Assets/Scenes を用意します。フォルダーは必ずUnityのProjectウィンドウ内で作りましょう。
  4. File > Save Project とシーンの保存を行います。

Unityではアセットと同名の .meta ファイルに識別用GUIDなどが保存されます。.metaファイルは削除せず、元のアセットとセットでGitに登録してください。 一方、Library は再生成できるキャッシュなのでGitの管理対象から外します。新規プロジェクトでは、.meta が表示され、シーンやPrefabがテキストで保存される設定が標準です。設定を変えていなければ操作は不要です。

GitHub Desktopでリポジトリを作成し、初回コミット

Unityプロジェクトには、Gitに登録しないほうがよいファイル(Library など)があります。これを除外する設定が .gitignore です。GitHub Desktopでは、リポジトリを作るときに Git IgnoreでUnityを選ぶと、.gitignore が自動で作られます。自分で作る必要はありません。

  1. エクスプローラーで、Unity Hubで作成した CoinCollectorTeam フォルダー(Assets、Packages、ProjectSettings が入っているプロジェクトのルート)を開きます。
  2. そのフォルダーごと、GitHub Desktopのウィンドウへドラッグ&ドロップします。Assets など中のフォルダーではなく、プロジェクトのルートを渡します。
  3. 「Gitリポジトリではない」と表示されたら、create a repository here(この場所にリポジトリを作成)を選びます。Local pathが既存のUnityプロジェクトフォルダー(リポジトリのルート)そのものになっていることを確認し、Git Ignore に Unity を選び、Create Repository を押します。プロジェクトの最上位フォルダー(Assets、Packages、ProjectSettings と同じ階層)に .gitignore が作られます。
  4. Changes に Assets、Packages、ProjectSettings、.gitignore などが表示され、Library が含まれていないことを確認します。
  5. Summaryに Initial Unity 6 project と入力し、Commit to main を実行します。
  6. Publish repository を押し、Keep this code private を選んで公開先をGitHubに作成します。

ドラッグ&ドロップがうまくいかない場合は、File > Add Local Repository からプロジェクトのフォルダーを指定しても、同じ画面に進めます。

Assets、Packages、ProjectSettings、.metaファイルは原則としてコミットします。 Library を一度コミットしてしまった場合、後から .gitignore に追記しただけでは既存の追跡は解除されません。

確認ポイント: GitHub上に Assets、Packages、ProjectSettings、.gitignore があり、Library が存在しなければ基本的に成功です。リポジトリに巨大なファイルやライセンス上問題のある素材が含まれていないかも確認してください。あわせて、内側に別の CoinCollectorTeam フォルダーができていないこと(Local pathがプロジェクトのルートそのものであること)も確認します。

STEP 2:Bさんを招待し、Cloneする

  1. AさんはGitHubの対象リポジトリで Settings > Collaborators(画面によっては Collaborators and teams)を開き、BさんのGitHubユーザー名を指定して招待します。
  2. Bさんは招待を承認します。
  3. BさんはGitHub Desktopで File > Clone Repository を選び、対象リポジトリと保存先フォルダーを指定してCloneします。
  4. BさんはUnity Hubから Clone先フォルダーを既存プロジェクトとして追加し、Aさんと同じバージョンのUnity 6で開きます。
  5. MainScene が開けることを確認します。

確認ポイント: AさんとBさんの双方が同じMainSceneを開けます。BさんはCloneしたフォルダー内に、さらに別のUnityプロジェクトを新規作成してはいけません。

STEP 3:ブランチを作って担当作業を分ける

AさんとBさんはそれぞれGitHub Desktopの Current Branch > New Branch から、最新の main を基点に次のブランチを作ります。

担当ブランチ名
Aさんfeature/player-movement
Bさんfeature/coin-collection

自分が作業しているブランチ名を、編集前に必ず確認してください。作業の終わりにはCommitして、Publish branch(2回目以降はPush origin)を実行します。

STEP 4:AさんはPlayerを作る

Aさんの feature/player-movement ブランチだけで作業します。

  1. Unityの GameObject > 2D Object > Sprites > Square などから四角いSpriteを作成し、名前をPlayerにします。青色にします。
  2. Rigidbody 2D を追加し、Gravity Scale = 0、Freeze Rotation Z = ON にします。
  3. Box Collider 2D を追加し、Is Trigger はOFFにします。
  4. PlayerMovement.cs を作成し、次の内容を入力します。
using UnityEngine;
using UnityEngine.InputSystem;

[RequireComponent(typeof(Rigidbody2D))]
public class PlayerMovement : MonoBehaviour
{
    [SerializeField] private float moveSpeed = 4f;

    private Rigidbody2D rb;
    private Vector2 moveInput;

    private void Awake()
    {
        rb = GetComponent<Rigidbody2D>();
    }

    private void Update()
    {
        Keyboard keyboard = Keyboard.current;
        if (keyboard == null)
        {
            moveInput = Vector2.zero;
            return;
        }

        float x = 0f;
        float y = 0f;

        if (keyboard.aKey.isPressed || keyboard.leftArrowKey.isPressed) x -= 1f;
        if (keyboard.dKey.isPressed || keyboard.rightArrowKey.isPressed) x += 1f;
        if (keyboard.sKey.isPressed || keyboard.downArrowKey.isPressed) y -= 1f;
        if (keyboard.wKey.isPressed || keyboard.upArrowKey.isPressed) y += 1f;

        moveInput = new Vector2(x, y).normalized;
    }

    private void FixedUpdate()
    {
        rb.linearVelocity = moveInput * moveSpeed;
    }
}
  1. Playerにスクリプトをアタッチして、Assets/Prefabs にドラッグし Player.prefab を作成します。
  2. シーン上のPlayerは削除し、Prefabだけを残します。 最終シーンへの配置は統合後に行います。
  3. コンパイルエラーがないこと、Player.prefab が存在することを確認してCommitします(例:Add player movement prefab)。Publish branch します。

注意: ここでは Update で入力を読み、FixedUpdate で Rigidbody 2D の速度を更新しています。Unity 6の Rigidbody2D.linearVelocity を使用します。ゲーム画面にフォーカスしてWASDキーまたは矢印キーを操作します。

STEP 5:BさんはCoinとスコアを作る

Bさんは feature/coin-collection ブランチのみで作業します。Playerの実装やMainSceneは編集しません。 代わりに、Prefab単体で提出できる機能を作ります。

Coin.cs

BさんのブランチにはAさんの PlayerMovement クラスがまだありません。そのため、相手のクラスを直接参照せず、Unity標準の Player タグで接触相手を判定します。これなら機能を別々のブランチで実装できます。

using UnityEngine;

public class Coin : MonoBehaviour
{
    private bool collected;

    private void OnTriggerEnter2D(Collider2D other)
    {
        if (collected || !other.CompareTag("Player")) return;

        collected = true;
        CoinCounter.AddCoin();
        Destroy(gameObject);
    }
}

CoinCounter.cs

using UnityEngine;

public class CoinCounter : MonoBehaviour
{
    private const int Goal = 3;
    private static int count;

    private void Awake()
    {
        count = 0;
    }

    public static void AddCoin()
    {
        count++;
    }

    private void OnGUI()
    {
        GUI.Label(new Rect(20, 20, 260, 40), $"Coins: {count} / {Goal}");
        if (count >= Goal)
        {
            GUI.Label(new Rect(20, 60, 260, 40), "CLEAR!");
        }
    }
}

この教材ではゲームを小さくするため、スコア表示だけは OnGUI で簡易表示します。製品向けの画面UIを作る場合は、Unity UIやUI Toolkitに置き換えるのが適切です。

CoinをPrefab化する

  1. GameObject > 2D Object > Sprites > Circle などから丸いSpriteを作り、Coinと命名して黄色にします。
  2. Circle Collider 2Dを追加し、Is TriggerをONにします。Coin自体にRigidbody 2Dは必要ありません。Player側のRigidbody 2Dを使用します。
  3. Coin.cs をアタッチし、Assets/Prefabs/Coin.prefab に保存します。
  4. 空のGameObject CoinCounter に CoinCounter.cs をアタッチし、Assets/Prefabs/CoinCounter.prefab に保存します。
  5. PlayerというTagがUnityのタグ一覧に存在することを確認します(標準のPlayerタグを利用)。タグの指定自体は、統合後にAさんがPlayerへ行います。
  6. シーン上に作成したCoin、CoinCounterのインスタンスは削除し、Prefabのみコミットします。
  7. Add coin collection prefabs としてCommitし、Publish branch します。

確認ポイント: Bさんのブランチに Coin.prefab、CoinCounter.prefab、2本のスクリプトがあり、MainScene.unityを変更していないことを確認します。

STEP 6:Pull Requestで2人の作業をまとめる

  1. Aさん、BさんがそれぞれGitHub Desktopで作業ブランチを Push origin まで済ませます。
  2. Preview Pull Request または Create Pull Request を選びます(GitHubのWeb画面が開きます)。
  3. base = main、compare = 自分の feature/... ブランチ になっていることを確認します。
  4. PRタイトルに何を追加したか、説明欄に編集ファイルと確認内容を書きます。
  5. 相手のPRをレビューし、意味の分からない変更があれば質問します。
  6. AさんのPR、続いてBさんのPRをGitHubで Merge pull request します。今回は編集ファイルが重ならない想定です。
  7. 2人ともGitHub Desktopでmainに切り替え、Fetch origin → Pull origin で最新を取り込みます。

Commit・Push・Pull・Mergeは別物です。 Commitは手元に履歴を残す、PushはGitHubへ送る、PullはGitHub側の変更を手元に取り込む、Mergeは別ブランチの変更を統合する操作です。

STEP 7:Aさんだけが完成シーンを組み立てる

ここからはAさんが、最新の main をPullしたあと feature/integrate-scene ブランチを新しく作って編集します。Bさんはこの間 MainScene を変更しません。

  1. MainSceneを開き、Player.prefabをシーンへ配置します。InspectorでTag = Playerを選びます。
  2. Coin.prefab をシーンへ3個配置します。Playerが簡単に近づける位置に置きます。Z座標は2D画面に合うよう通常0とします。
  3. CoinCounter.prefab を1個配置します。
  4. Main Cameraの位置を確認し、すべてのSpriteがGameビューに表示されるよう調整します。
  5. Playを押し、WASDまたは矢印キーでPlayerが動くか確認します。
  6. Coinに触れるたびにCoinが消え、Coins: 1 / 3 → 2 / 3 → 3 / 3 と変わり、CLEAR! が表示されるか確認します。
  7. Playを終了し、MainSceneを保存してCommit → Push → Pull Request → 相手レビュー → Mergeします。
  8. Bさんは最新のmainをPullし、BさんのPCでも同じゲームが動くことを確認します。

成功条件: AさんのPCだけでなく、BさんのPCでも正常に動作すること。これが今回のチーム開発の最重要確認です。

STEP 8:練習用ファイルでコンフリクトを安全に体験する

初心者の最初の競合練習に MainScene.unity を使用するのはおすすめしません。まず、Unityのアセットと関係のないテキストファイル team-note.txt をリポジトリのルートに作り、今日の目標: コインを集める と書いてmainにコミットします。

  1. 2人とも最新のmainをPullします。
  2. Bさんは、まずこの時点のmainから practice/conflict-b ブランチを作ります(まだファイルは編集しません)。 次にAさんは practice/conflict-a ブランチを作り、同じ1行を 今日の目標: 青いプレイヤーを動かす に変更、CommitしてPRからmainにマージします。
  3. Bさんは最初に作成しておいた practice/conflict-b ブランチ上で同じ1行を 今日の目標: 黄色いコインを集める に変更し、Commit・PushしてPRを作ります。
  4. BさんのPRには自動マージできない旨が表示される可能性があります。BさんはGitHub Desktopで practice/conflict-b に切り替え、最新のmainをFetch/Pullで取得し、Branch > Merge into current branch からmainを統合します。
  5. 競合が発生したら team-note.txt をエディターで開き、競合マーカーを確認して 今日の目標: プレイヤーを動かしてコインを集める の1行に手動修正します。
  6. 解決済みにしてMerge commitを作成し、PushしてPRをマージします。最後に二人とも最新mainをPullします。

※ GitHub Desktopの競合画面とメニューはバージョンにより違います。マージを取り消したい場合は、無理に解決せず、講師と現状を確認してください。競合の練習では Assets 内のSceneやPrefabを編集しません。

よくある失敗と確認方法

症状原因の候補最初に確認すること
BさんのUnityでプロジェクトが開けないClone先とHubの登録先が違う/Editorバージョン不一致Assets、Packages、ProjectSettings がClone先直下にあるか
Library が大量にChangesへ表示されるリポジトリ作成時にGit Ignoreを選んでいない/.gitignoreの配置・追跡設定が不適切.gitignore がリポジトリ直下にあるか、すでに追跡されていないか
Missing Scriptが出る.metaやスクリプトが欠けた/コンパイルエラーConsole、.meta、Gitの変更履歴、Version Control と Asset Serialization の設定
キーを押しても動かないInput Systemが無効(Active Input Handling が旧設定)/GameビューにフォーカスなしActive Input Handling、Package ManagerのInput System、Gameビュー
コインに触れても反応しないIs TriggerがOFF/Playerタグがない/Rigidbody 2DがないCoinのCollider 2D、PlayerのTagとRigidbody 2D
PRに予定外のシーン変更がある担当外のMainSceneを編集したGitHub DesktopのChanges、ブランチ名
相手の追加機能が見えないmainが最新でないFetch origin、Pull origin、現在のブランチ

ゲームが動いても、GitHub DesktopのChangesに意図しないファイルが残っていないか確認します。Unityは開いただけで一部の設定ファイルを書き換えることがあります。理解できない変更はまとめてコミットせず、内容を確認してください。

提出課題:担当を交換してもう一度

今度はAさんがCoinを4個に増やす仕様を、BさんがPlayerの移動速度を変更する仕様を担当します。それぞれ新しいブランチを作り、PRで変更点を説明してから統合してください。必要ならAさんはCoinの数を増やす最終シーンの編集、BさんはPlayer.prefabの速度変更を担当し、同じファイルを同時編集しないようにします。

提出時には次の内容をREADMEにまとめます。

  • リポジトリURLと完成画面(画像や動画は任意)
  • 自分の担当した機能と変更ファイル
  • 自分が作成したPRのURL
  • チームで困ったことと解決した方法
  • Commit、Push、Pull、Pull Request の違いを各1行で説明

評価基準: ゲームが動くことだけでなく、各自が自分の変更を説明できること、相手のPRを確認したこと、両方のPCで再現できることを重視します。

まとめ:ゲーム制作より重要なのは「共有できる開発」

今回のチュートリアルで学んだのは、GitHub Desktopのボタンの位置だけではありません。「役割を分ける → ブランチで作業する → Commit/Pushする → PRで相手に見てもらう → マージする → 双方で動作確認する」というチーム開発の最小単位です。

最初は二人・小さなゲーム・別々のPrefabで成功体験を作りましょう。慣れたら3〜4人での機能分担、Issueによるタスク管理、Unityのシーン競合の解決へ進むと、段階的に難易度を上げられます。

関連するソフトライム記事

公式資料

訪問数 12 回, 今日の訪問数 12回

広告