【Unity 6】GitHub Desktopでチーム開発|WinForms経験者向け・2人で作るコイン収集ゲーム(6ステップ)

広告

Gitチーム開発シリーズ・Unity 6 実践編:シリーズ目次|WinFormsで2人開発|ブランチを体験する|Pull Requestを体験する

WinFormsで2人開発、ブランチ、Pull Requestを体験した人向けです。Gitの操作は既習として進めます。今回は同じ流れをUnityに持ち込み、Prefabで担当を分け、シーンは最後に1人が統合する方法を学びます。完成条件は、AさんとBさん両方のPCでPlayerが動き、Coinを3個集めるとCLEAR!が表示されることです。

WinFormsでの経験をUnityに置き換える

WinFormsで経験したことUnityで行うこと
担当ごとにクラス・画面を分けるAさんはPlayer、BさんはCoinとスコアを、それぞれスクリプトとPrefabで作る
Designer生成ファイルを同時編集しないMainScene.unityを担当ブランチでは編集せず、最後にAさんが配置する
担当ブランチからPRを出して統合する同じ手順。AさんのPRを先にマージし、BさんはUpdate from main後にPRを完成させる

担当の約束:AさんはPlayerMovement.csとPlayer.prefab、BさんはCoin.cs・CoinCounter.cs・Coin.prefab・CoinCounter.prefabを担当します。MainScene.unityは統合時にAさんだけが編集します。

STEP 1:Unityプロジェクトを共同作業用に準備する

  1. 2人とも同じUnity 6のEditorバージョンを使い、C#スクリプトを開けるようにします。入力にはUnity 6の標準設定で使えるInput Systemを使用します。
  2. Aさんは2DプロジェクトCoinCollectorTeamを作り、標準で用意されているAssets/ScenesフォルダーにMainScene.unityを保存します。UnityのProjectウィンドウでAssets/ScriptsとAssets/Prefabsを用意します。
  3. プロジェクトのルートをGitHub Desktopでリポジトリにし、Git IgnoreはWinForms実習の「Visual Studio」ではなく「Unity」を選びます。Assets、Packages、ProjectSettingsと.metaを共有し、自動生成されるLibraryは含めません。

確認:リポジトリのルート直下にAssets、Packages、ProjectSettings、.gitignoreがあります。LibraryはChangesにありません。.metaは対応するアセットと一緒に残します。

GitHub Desktopでリポジトリを作る操作を確認する

C#の簡単なアプリをGitで管理しよう!初心者向けコミット・Push実践チュートリアルの「GitHub Desktopでリポジトリを作る」とGitHub公式:GitHub Desktopを使った最初のリポジトリ作成方法を参照してください。公式記事の新規作成例は新しいフォルダーを作る手順なので、この教材では既存のUnityプロジェクトのルートを指定し、Git IgnoreでUnityを選んでから作成・Publishします。ルートの内側に同名のプロジェクトをもう1つ作らないようにします。通常はInitial commitが自動で作られます。もしChangesにUnityプロジェクトのファイルが残っている場合だけ、内容を確認してCommitしてからPublishしてください。

入力が反応しない場合

まずGameビューにフォーカスがあるか確認します。using UnityEngine.InputSystem;でエラーが出る場合だけ、Package ManagerでInput Systemが導入されているか確認してください。必要に応じてEdit > Project Settings > Player > Active Input HandlingをInput System Package (New)またはBothにします。変更後に求められたらUnity Editorを再起動します。

STEP 2:Bさんが共有プロジェクトを開く

  1. Aさんはリポジトリを作成したら、Publish repositoryでGitHubに共有し、BさんをCollaboratorに招待します。
  2. Bさんは招待を承認し、GitHub Desktopで対象リポジトリをCloneします。
  3. BさんはUnity HubにClone先を既存プロジェクトとして追加し、Aさんと同じEditorで開きます。新しいUnityプロジェクトをClone先に作成しません。

確認:2人とも同じMainSceneを開けます。ここまではWinFormsの「Aさんが作成・共有、BさんがClone」と同じ流れです。

STEP 3・4の分担とSTEP 6の統合:担当ブランチにはMainScene.unityを含めず、Prefabを統合してからAさんがシーンを組み立てます。

STEP 3:AさんがPlayerのPrefabを作る

Aさんは最新のmainからfeature/player-movementを作ります。Bさんはfeature/coin-collectionを作ります。作業前にGitHub Desktopの現在のブランチを確認してください。

  1. Aさんは青い四角のPlayerを作り、Rigidbody 2D(Gravity Scale = 0、Freeze Rotation Z = ON)とBox Collider 2D(Is Trigger = OFF)を追加します。
  2. PlayerMovement.csを作り、次のコードを入力してPlayerにアタッチします。
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. 一時的にシーンへ置いてPlayし、WASDまたは矢印キーで上下左右に動くことを確かめます。Playを止めてPlayerをシーンから削除し、MainScene.unityの変更をCommitに含めません。
  3. ChangesにPlayerMovement.csとPlayer.prefabおよび対応する.metaだけがあることを確認し、Commit・Pushします。

Unityでの要点:動作確認にはシーンを使いますが、担当間で渡す成果物はPrefabとスクリプトです。シーンの最終配置はSTEP 6で行います。

補足:UpdateとFixedUpdate

このコードはUpdateで入力を読み、FixedUpdateでRigidbody 2DのlinearVelocityを更新します。

STEP 4:BさんがCoinとスコアのPrefabを作る

Bさんはfeature/coin-collectionだけで作業します。Aさんのスクリプトはまだ自分のブランチにないため、接触判定にはUnity標準のPlayerタグを使います。

Coin.cs

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!");
        }
    }
}
  1. 黄色い丸のCoinを作り、Circle Collider 2DのIs TriggerをONにしてCoin.csをアタッチします。Assets/Prefabs/Coin.prefabに保存します。
  2. 空のGameObjectにCoinCounter.csを付け、Assets/Prefabs/CoinCounter.prefabに保存します。
  3. 一時的にCoinとCoinCounterをシーンに置き、Playerタグ・Rigidbody 2D・Box Collider 2Dを付けたテスト用オブジェクトをCoinに接触させ、Coinが消えてカウントが増えるか確認します。
  4. テスト用オブジェクトとシーン上のPrefabを削除します。MainScene.unityをCommitに含めず、2本のスクリプト・2つのPrefab・対応する.metaをCommit・Pushします。

確認:両者の担当PRにMainScene.unityの変更が含まれません。

補足:簡易スコア表示

OnGUIはこの実習の簡易表示です。staticのAddCoin()をCoinから呼びます。最終シーンにCoinCounterは1個だけ配置します。

STEP 5:PRを順番に統合する

図と実際の手順の違い:黄色いBさんの線には、AさんのPRがマージされた後に最新のmainを取り込む操作が描かれていません。実際にはAさんをマージ → BさんがmainをPull → Bさんの作業ブランチでUpdate from main → Push → BさんのPRを確認してマージの順です。

PR作成・レビュー・マージはWinFormsで学習した手順を使います。操作を確認したい場合はPull Requestを体験する(Gitチーム開発)を参照してください。今回は先にAさん、次にBさんの順で統合します。

  1. 2人とも担当ブランチをPushし、base = main、compare = 自分のfeature/...でPRを作ります。変更ファイルと動作確認結果を書き、相手のPRをレビューします。
  2. AさんのPRをmainへマージします。
  3. BさんはGitHub Desktopでmainに切り替え、Fetch origin → Pull originを行います。自分のfeature/coin-collectionへ戻り、Branch > Update from mainを実行します。変更が入ったらPushします。
  4. BさんのPRを再確認してマージします。2人ともmainをPullします。

Bさんが最新のmainを取り込む順序

確認:Bさんの作業ブランチにAさんのPlayerが入り、最終的なmainにはPlayer・Coin・CoinCounterのPrefabが揃っています。mainをPullしただけでは、Bさんの作業ブランチは更新されません。

STEP 6:Aさんがシーンを組み立て、2人で再現する

Aさんは最新のmainからfeature/integrate-sceneを作ります。この段階で初めてMainScene.unityを編集します。Bさんは同時にこのシーンを変更しません。

  1. Player.prefabを配置してTag = Playerを指定します。
  2. Coin.prefabを3個、CoinCounter.prefabを1個配置します。全てがGameビューに見えるようMain Cameraを確認します。
  3. Playで移動と接触を試し、Coins: 1 / 3 → 2 / 3 → 3 / 3、最後にCLEAR!を確認します。
  4. Playを止めてシーンを保存し、Commit・Push・PR・相手のレビュー・マージを行います。
  5. Bさんも最新のmainをPullし、BさんのPCで同じゲームが動くことを確認します。

完成条件:片方のPCで動くだけでは完了ではありません。両方のPCでシーンと機能を再現できれば成功です。

困ったときの確認

症状最初に確認すること
Bさんのプロジェクトが開けないClone先直下にAssets・Packages・ProjectSettingsがあるか、Editorバージョンが一致するか
Missing Scriptスクリプトと対応する.meta、Consoleのエラー
Playerが動かないGameビューのフォーカス、Input System設定
Coinに触れても反応しないCoinのIs Trigger、Playerタグ、PlayerのRigidbody 2D
相手の機能が見えない現在のブランチ、mainのPull、作業ブランチのUpdate from main

発展学習

競合解消は、まずWinFormsのシリーズで扱ったテキストファイルの演習を復習してください。UnityのMainScene.unityやPrefabでの競合解消は、今回の完成条件には含めません。次の練習では担当を交換し、AさんはCoinの目標を4個に、BさんはPlayerの移動速度を変更してみましょう。新しいブランチで別々のファイルを編集し、PRで変更内容を説明します。

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

公式資料

次の実践:Unity実践2 — 4人でUI・効果音・ビルドまで完成させる。この2人実践を終えたら、基本制作3日間・18限で担当を広げてみましょう。Gitチーム開発シリーズの目次へ。

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

広告