C# Unity入門|初心者が最短でゲームを作れる基礎文法と実装手順

はじめに

Unityでゲームを作りたいと思ったとき、多くの初心者が最初にぶつかるのが「C#をどう学べばいいのか」という悩みです。Unityは直感的にオブジェクトを配置できるゲームエンジンですが、キャラクターを動かす、スコアを増やす、敵を出す、ゲームオーバーを判定するといった処理にはC#の知識が必要になります。

ただし、C#の文法を最初から最後まで完璧に覚える必要はありません。Unityでゲームを作るために必要なC#は、まず「ゲーム制作でよく使う部分」から学ぶのが近道です。

この記事では、「csharp unity」や「C# Unity 入門」と検索している初心者向けに、UnityでC#を使うための基礎文法、スクリプトの基本構造、実装手順、つまずきやすいエラーの解決策までをまとめて解説します。

1. C# Unity入門で最初に知るべきこと

1-1. 「csharp unity」で検索する人の悩みとこの記事で解決できること

「csharp unity」で検索する人の多くは、次のような悩みを持っています。

Unityを始めたけれどC#スクリプトの書き方が分からない、StartやUpdateの意味が分からない、エラーが出ても原因を特定できない、サンプルコードをコピーしても自分で改造できない、どの順番で学べばゲームを完成させられるのか分からない。

この記事では、UnityでC#を使ううえで最低限必要な考え方を、ゲーム制作の流れに沿って解説します。文法だけを切り離して覚えるのではなく、「プレイヤーを動かす」「アイテムを取る」「スコアを表示する」といった実装と結びつけながら学べる構成にしています。

1-2. UnityでC#が使われる理由

Unityでは、ゲーム内の動きを制御するためにC#が使われます。たとえば、プレイヤーの移動、ジャンプ、敵の行動、カメラ追従、UI表示、効果音の再生、ステージ遷移などはC#スクリプトで実装できます。

C#は読みやすく、型が明確で、大規模なゲーム開発にも対応しやすい言語です。Unity側にはGameObject、Transform、Rigidbody、Collider、Inputなどの便利な機能が用意されており、C#からそれらを操作することでゲームの仕組みを作れます。

つまりUnityにおけるC#は、ゲームオブジェクトに命令を与えるための言語です。

1-3. C#単体の学習とUnity用C#学習の違い

C#単体の学習では、コンソールアプリ、Webアプリ、業務システムなどを作るための文法や設計を幅広く学びます。一方、Unity用のC#学習では、Unity Editor上のオブジェクトを操作することが中心になります。

たとえばC#単体では次のような内容を学びます。

C#
int score = 100;
Console.WriteLine(score);

一方、Unityでは次のようにGameObjectやTransformを操作します。

C#
transform.position += new Vector3(1, 0, 0);

Unity初心者は、C#の文法をすべて学んでからUnityに進むよりも、Unityでよく使うC#の書き方を先に覚えるほうが挫折しにくいです。

1-4. 初心者が最短でゲーム制作に進むための学習順序

初心者が最短でゲーム制作に進むなら、次の順番で学ぶのがおすすめです。

まずUnity Editorの基本操作を覚えます。次にC#スクリプトの作成方法、StartとUpdate、変数、if文、メソッドを学びます。その後、Transformでオブジェクトを動かし、Inputで操作を受け取り、Colliderで当たり判定を実装します。

さらに、Instantiateでオブジェクトを生成し、Destroyで削除し、UIでスコアを表示できるようになれば、簡単なミニゲームを完成させる力が身につきます。

最初から高度な設計や複雑なクラス構成を目指す必要はありません。まずは小さなゲームを1つ完成させることが最優先です。

2. UnityとC#の開発環境を準備する

2-1. Unity HubとUnity Editorのインストール手順

Unityで開発を始めるには、まずUnity Hubをインストールします。Unity Hubは、Unity Editorのバージョン管理、新規プロジェクト作成、既存プロジェクトの管理を行うためのツールです。

Unity Hubをインストールしたら、Unity Editorを追加します。初心者は、安定版のLTS版を選ぶと安心です。LTS版は長期サポート版で、学習中に不要なトラブルが起きにくいというメリットがあります。

インストール時には、必要に応じてVisual Studio、Android Build Support、iOS Build Supportなどを追加できます。最初はPC向けの簡単なゲーム制作から始める場合、標準構成で問題ありません。

2-2. Visual StudioまたはVisual Studio Codeの設定

UnityのC#スクリプトは、Visual StudioまたはVisual Studio Codeで編集できます。初心者にはVisual Studioが分かりやすいです。Unityとの連携機能が充実しており、コード補完やエラー表示も使いやすいからです。

Unity側では、外部スクリプトエディターを設定します。

Unity Editorのメニューから「Edit」→「Preferences」→「External Tools」を開き、External Script Editorに使用するエディターを指定します。

正しく設定できていれば、UnityでC#スクリプトをダブルクリックしたときに、指定したエディターが開きます。

2-3. 新規プロジェクトの作成方法

Unity Hubを開き、「New project」から新規プロジェクトを作成します。初心者は2Dまたは3Dのテンプレートを選びましょう。

2Dゲームを作るなら2Dテンプレート、立体的な空間でゲームを作るなら3Dテンプレートを選びます。最初に学ぶ場合は、オブジェクトの動きが分かりやすい3Dの玉転がしゲームや、2Dのクリックゲームがおすすめです。

プロジェクト名は分かりやすく英数字で付けると管理しやすくなります。保存場所も後から見つけやすいフォルダにしておきましょう。

2-4. C#スクリプトの作成と保存場所

UnityでC#スクリプトを作成するには、Projectウィンドウ内で右クリックし、「Create」→「C# Script」を選びます。

スクリプトはAssetsフォルダ内に保存されます。プロジェクトが大きくなるとファイルが増えるため、初心者のうちから「Scripts」フォルダを作って、その中にC#スクリプトを保存する習慣をつけるとよいです。

たとえば、次のようなフォルダ構成にすると整理しやすくなります。

Assets
├─ Scenes
├─ Scripts
├─ Prefabs
├─ Materials
└─ Sprites

スクリプトを作成したら、GameObjectにドラッグ&ドロップすることで、そのオブジェクトに処理を追加できます。

2-5. スクリプト名とクラス名を一致させる理由

UnityのC#スクリプトでは、ファイル名とクラス名を一致させる必要があります。

たとえば「PlayerController.cs」というスクリプトを作った場合、クラス名も次のようにします。

C#
using UnityEngine;

public class PlayerController : MonoBehaviour
{
}

ファイル名が「PlayerController.cs」なのに、クラス名が「PlayerMove」になっていると、Unityがスクリプトを正しく認識できない場合があります。

初心者によくあるミスなので、スクリプト名を変更したときは、クラス名も同じ名前になっているか必ず確認しましょう。

3. Unity C#スクリプトの基本構造を理解する

3-1. using UnityEngineとは何か

UnityでC#スクリプトを作ると、最初に次のようなコードが書かれています。

C#
using UnityEngine;

これは、Unityが用意している機能をC#スクリプト内で使えるようにするための宣言です。

Transform、GameObject、Vector3、Rigidbody、Collider、Input、Timeなど、Unity開発でよく使う機能の多くはUnityEngine名前空間に含まれています。

そのため、UnityのC#スクリプトでは基本的にusing UnityEngine;が必要になります。

3-2. classとMonoBehaviourの役割

UnityのC#スクリプトは、基本的にクラスとして書きます。

C#
public class PlayerController : MonoBehaviour
{
}

classは処理をまとめる設計図のようなものです。PlayerControllerはクラス名で、プレイヤーを操作するための処理をここに書いていきます。

MonoBehaviourは、UnityのGameObjectにアタッチして使うための特別なクラスです。MonoBehaviourを継承することで、Start、Update、OnCollisionEnter、OnTriggerEnterなど、Unity特有のメソッドを使えるようになります。

UnityでC#を書くときは、「MonoBehaviourを継承したクラスをGameObjectに追加して動かす」と覚えておきましょう。

3-3. StartメソッドとUpdateメソッドの違い

Unity初心者が最初に理解すべきメソッドが、StartとUpdateです。

C#
void Start()
{
Debug.Log("ゲーム開始時に1回だけ実行");
}

void Update()
{
Debug.Log("毎フレーム実行");
}

Startは、ゲーム開始時やオブジェクトが有効になったときに1回だけ実行されます。初期設定、変数の初期化、コンポーネントの取得などに使います。

Updateは、ゲーム中に毎フレーム実行されます。プレイヤー入力の取得、キャラクター移動、タイマー処理など、常に確認したい処理に使います。

ただし、Updateに何でも書きすぎるとコードが読みにくくなります。処理が増えてきたらメソッドに分けることが大切です。

3-4. GameObjectとComponentの関係

Unityでは、シーン上に配置されるものをGameObjectと呼びます。プレイヤー、敵、カメラ、ライト、アイテム、UIなどはすべてGameObjectです。

GameObject自体は空の入れ物のような存在で、そこにComponentを追加することで機能を持たせます。

たとえば、プレイヤーには次のようなComponentを追加できます。

Transformは位置・回転・大きさを管理します。Rigidbodyは物理挙動を担当します。Colliderは当たり判定を担当します。AudioSourceは音を再生します。C#スクリプトもComponentの一種です。

Unity C#では、このComponentを取得して操作することがよくあります。

C#
Rigidbody rb;

void Start()
{
rb = GetComponent<Rigidbody>();
}

このように、GameObjectとComponentの関係を理解すると、Unityの仕組みが一気に分かりやすくなります。

3-5. Inspectorに変数を表示する方法

Unityでは、C#スクリプト内の変数をInspectorに表示して、エディター上から値を変更できます。

C#
public float moveSpeed = 5f;

publicを付けると、Inspectorに表示されます。プレイヤーの移動速度、ジャンプ力、HP、スコア倍率などを調整したいときに便利です。

ただし、外部から自由に変更されたくない変数までpublicにするのは避けたほうがよいです。その場合は[SerializeField]を使います。

C#
[SerializeField] private float moveSpeed = 5f;

この書き方なら、変数はprivateのままInspectorに表示できます。Unity C#ではよく使う書き方なので覚えておきましょう。

4. ゲーム制作で使うC#基礎文法

4-1. 変数とデータ型:int、float、bool、string

変数は、数値や文字などのデータを入れておく箱です。Unity C#でよく使う基本的なデータ型には、int、float、bool、stringがあります。

C#
int score = 0;
float moveSpeed = 5.0f;
bool isGameOver = false;
string playerName = "Player";

intは整数を扱います。スコア、残機、アイテム数などに使います。

floatは小数を扱います。移動速度、ジャンプ力、時間、座標などに使います。Unityでは小数の末尾にfを付けます。

boolはtrueまたはfalseを扱います。ゲームオーバーかどうか、ジャンプ中かどうか、アイテムを持っているかどうかなどの判定に使います。

stringは文字列を扱います。プレイヤー名、メッセージ、UI表示などに使います。

4-2. 演算子と条件分岐:if文でゲームの状態を変える

ゲームでは、「もしHPが0以下ならゲームオーバー」「もしアイテムに触れたらスコアを増やす」といった条件分岐が頻繁に登場します。

C#
int hp = 10;

void Update()
{
if (hp <= 0)
{
Debug.Log("ゲームオーバー");
}
}

比較には、次のような演算子を使います。

C#
score == 100  // 等しい
score != 100 // 等しくない
hp > 0 // より大きい
hp < 0 // より小さい
hp >= 10 // 以上
hp <= 0 // 以下

条件を組み合わせる場合は、&&||を使います。

C#
if (hp > 0 && isGameOver == false)
{
Debug.Log("プレイ中");
}

if文はゲームの状態を変える基本です。Unity C#を学ぶなら、最初にしっかり理解しておきましょう。

4-3. 繰り返し処理:for文とwhile文の使いどころ

同じ処理を何度も実行したい場合は、繰り返し処理を使います。

for文は、回数が決まっている繰り返しに向いています。

C#
for (int i = 0; i < 5; i++)
{
Debug.Log(i);
}

たとえば、敵を5体生成する、アイテムを10個配置する、配列の中身を順番に確認するような場面で使います。

while文は、条件を満たしている間だけ繰り返す処理に使います。

C#
int count = 0;

while (count < 3)
{
Debug.Log("繰り返し");
count++;
}

ただし、while文は条件がずっとtrueのままだと無限ループになります。Unity Editorが固まる原因になるため、初心者はfor文から使い始めると安全です。

4-4. メソッドの作り方と処理を分ける考え方

メソッドは、処理をまとめて名前を付けたものです。Updateの中にすべての処理を書くと読みにくくなるため、役割ごとにメソッドへ分けます。

C#
void Update()
{
MovePlayer();
CheckGameOver();
}

void MovePlayer()
{
float x = Input.GetAxis("Horizontal");
transform.position += new Vector3(x, 0, 0) * 5f * Time.deltaTime;
}

void CheckGameOver()
{
if (transform.position.y < -5f)
{
Debug.Log("ゲームオーバー");
}
}

このように処理を分けると、「プレイヤーを動かす処理」「ゲームオーバーを確認する処理」が分かりやすくなります。

初心者のうちは、1つのメソッドに多くの処理を書きすぎないことを意識しましょう。

4-5. 配列とListで複数のオブジェクトを管理する

複数のデータやオブジェクトを管理したいときは、配列やListを使います。

配列は、数が決まっているデータを扱うときに便利です。

C#
int[] scores = new int[3];

scores[0] = 100;
scores[1] = 200;
scores[2] = 300;

Listは、後から要素を追加・削除しやすいデータ構造です。

C#
using System.Collections.Generic;
using UnityEngine;

public class ItemManager : MonoBehaviour
{
public List<GameObject> items = new List<GameObject>();

void Start()
{
Debug.Log(items.Count);
}
}

Unityでは、複数の敵、アイテム、弾、ステージ情報などを管理するときにListがよく使われます。

4-6. クラスとインスタンスの基本

クラスは設計図、インスタンスは設計図から作られた実体です。

たとえば、Enemyというクラスを作るとします。

C#
public class Enemy
{
public int hp;
public int attack;
}

このEnemyクラスから、複数の敵データを作れます。

C#
Enemy slime = new Enemy();
slime.hp = 10;
slime.attack = 2;

Enemy boss = new Enemy();
boss.hp = 100;
boss.attack = 20;

UnityのGameObjectも、シーン上に配置された実体として考えると理解しやすいです。PrefabをInstantiateで生成する処理も、設計図から実体を作るイメージに近いです。

5. Unity特有のC#実装を学ぶ

5-1. Transformで位置・回転・大きさを操作する

Transformは、GameObjectの位置、回転、大きさを管理するComponentです。Unity C#では非常によく使います。

位置を変更する例です。

C#
transform.position = new Vector3(0, 1, 0);

現在位置から右に移動する例です。

C#
transform.position += new Vector3(1, 0, 0);

回転させる場合は、Rotateを使えます。

C#
transform.Rotate(0, 90, 0);

大きさを変える場合は、localScaleを使います。

C#
transform.localScale = new Vector3(2, 2, 2);

プレイヤー移動、敵の向き変更、アイテムの回転演出など、Transform操作はゲーム制作の基本です。

5-2. Inputでキーボードやマウス入力を取得する

プレイヤーの操作を受け取るにはInputを使います。

C#
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
Debug.Log("スペースキーが押された");
}
}

キーを押している間ずっと処理したい場合はGetKeyを使います。

C#
if (Input.GetKey(KeyCode.RightArrow))
{
transform.position += new Vector3(1, 0, 0) * Time.deltaTime;
}

マウスクリックを取得する場合は次のように書けます。

C#
if (Input.GetMouseButtonDown(0))
{
Debug.Log("左クリック");
}

Unityには新しいInput Systemもありますが、初心者がC# Unityの基礎を学ぶ段階では、まず従来のInputの考え方を理解するとスムーズです。

5-3. Rigidbodyで物理挙動を扱う

Rigidbodyは、GameObjectに物理挙動を持たせるComponentです。重力、衝突、力を加える処理などに使います。

プレイヤーにRigidbodyを追加して、力を加える例です。

C#
using UnityEngine;

public class PlayerController : MonoBehaviour
{
private Rigidbody rb;

void Start()
{
rb = GetComponent<Rigidbody>();
}

void FixedUpdate()
{
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");

Vector3 force = new Vector3(x, 0, z);
rb.AddForce(force);
}
}

Rigidbodyを使う物理処理は、UpdateではなくFixedUpdateに書くのが基本です。FixedUpdateは物理演算のタイミングに合わせて実行されるため、挙動が安定しやすくなります。

5-4. Colliderと当たり判定の基本

Colliderは、GameObjectの当たり判定を担当するComponentです。Box Collider、Sphere Collider、Capsule Colliderなどがあります。

当たり判定には、大きく分けてCollisionとTriggerがあります。

Collisionは物理的にぶつかる判定です。

C#
void OnCollisionEnter(Collision collision)
{
Debug.Log("何かにぶつかった");
}

Triggerは、すり抜けながら接触を検知する判定です。アイテム取得やゴール判定によく使います。

C#
void OnTriggerEnter(Collider other)
{
Debug.Log("トリガーに触れた");
}

Triggerを使う場合は、Colliderの「Is Trigger」にチェックを入れます。また、少なくとも一方のGameObjectにRigidbodyが必要です。

5-5. Instantiateでオブジェクトを生成する

Instantiateは、ゲーム中にオブジェクトを生成するための関数です。弾、敵、アイテム、エフェクトなどを出すときに使います。

C#
public GameObject bulletPrefab;

void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
Instantiate(bulletPrefab, transform.position, transform.rotation);
}
}

bulletPrefabには、Inspectorから生成したいPrefabを設定します。

Instantiateを使うと、ゲーム中に同じオブジェクトを何度も生成できます。シューティングゲームの弾や、ランダムに出現する敵などに欠かせない機能です。

5-6. Destroyでオブジェクトを削除する

Destroyは、GameObjectを削除するための関数です。

C#
Destroy(gameObject);

一定時間後に削除したい場合は、第二引数に秒数を指定します。

C#
Destroy(gameObject, 3f);

弾が画面外に出たとき、敵を倒したとき、アイテムを取得したときなどに使います。

C#
void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Player"))
{
Destroy(gameObject);
}
}

不要なオブジェクトを残し続けると処理が重くなるため、生成したオブジェクトは適切に削除しましょう。

5-7. Time.deltaTimeでフレームレートに依存しない処理を書く

Updateは毎フレーム実行されますが、1秒間に何回実行されるかはPCや実行環境によって変わります。そのため、移動処理にそのまま数値を足すと、フレームレートによって速度が変わってしまいます。

悪い例です。

C#
transform.position += new Vector3(1, 0, 0);

この書き方では、フレーム数が多い環境ほど速く動きます。

Time.deltaTimeを使うと、1フレームにかかった時間を考慮できます。

C#
float speed = 5f;

void Update()
{
transform.position += new Vector3(1, 0, 0) * speed * Time.deltaTime;
}

Unity C#で移動、タイマー、アニメーション的な処理を書くときは、Time.deltaTimeを使う習慣をつけましょう。

6. 初心者向けミニゲームを作る実装手順

6-1. 作るゲームの完成イメージ

ここでは、初心者向けに「プレイヤーを動かしてアイテムを集めるゲーム」を作る流れを考えます。

完成イメージはシンプルです。プレイヤーはキーボードで移動します。ステージ上にはアイテムが配置されています。プレイヤーがアイテムに触れるとスコアが増え、アイテムは消えます。障害物に触れたり、ステージ外に落ちたりするとゲームオーバーになります。

このミニゲームには、Unity C#の基礎が多く含まれています。Transform、Input、Rigidbody、Collider、UI、if文、変数、メソッドなどを実践的に学べます。

6-2. プレイヤーオブジェクトを作成する

まず、シーン上にプレイヤーを作成します。3DならSphereやCube、2DならSpriteを使うと簡単です。

3Dの場合は、Hierarchyで右クリックし、「3D Object」→「Sphere」を選びます。名前をPlayerに変更し、RigidbodyとColliderが付いているか確認します。

地面としてPlaneを追加し、プレイヤーが落ちないようにします。カメラの位置も調整して、プレイヤーとステージが見えるようにしましょう。

プレイヤーにはTagを設定しておくと、当たり判定で判別しやすくなります。InspectorからTagを「Player」に設定します。

6-3. C#でプレイヤーを移動させる

プレイヤーを動かすために、PlayerControllerというC#スクリプトを作成します。

C#
using UnityEngine;

public class PlayerController : MonoBehaviour
{
[SerializeField] private float moveSpeed = 5f;

private Rigidbody rb;

void Start()
{
rb = GetComponent<Rigidbody>();
}

void FixedUpdate()
{
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");

Vector3 movement = new Vector3(x, 0, z);
rb.AddForce(movement * moveSpeed);
}
}

このスクリプトをPlayerにアタッチします。実行すると、キーボードの矢印キーやWASDでプレイヤーが動きます。

物理挙動で動かしているため、移動処理はFixedUpdateに書いています。

6-4. アイテムや障害物を配置する

次に、ステージ上にアイテムを配置します。3DならCubeやSphereを小さくして、分かりやすい色のMaterialを付けるとよいです。

アイテムにはColliderを付け、Is Triggerにチェックを入れます。これにより、プレイヤーが触れたときに通り抜けつつ接触を検知できます。

アイテムには「Item」というTagを設定しておくと便利です。障害物を作る場合は「Obstacle」というTagを設定します。

Tagを使うことで、当たり判定時に何に触れたのかをC#で判別できます。

6-5. 当たり判定でスコアを増やす

プレイヤーがアイテムに触れたらスコアを増やす処理を実装します。

まずはPlayerControllerにスコア変数を追加します。

C#
using UnityEngine;

public class PlayerController : MonoBehaviour
{
[SerializeField] private float moveSpeed = 5f;

private Rigidbody rb;
private int score = 0;

void Start()
{
rb = GetComponent<Rigidbody>();
}

void FixedUpdate()
{
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");

Vector3 movement = new Vector3(x, 0, z);
rb.AddForce(movement * moveSpeed);
}

void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Item"))
{
score++;
Debug.Log("Score: " + score);
Destroy(other.gameObject);
}
}
}

OnTriggerEnterは、Triggerに設定されたColliderに触れたときに実行されます。CompareTag("Item")でアイテムかどうかを判定し、スコアを増やしてからアイテムを削除しています。

6-6. UIでスコアを表示する

Debug.Logだけではゲーム画面にスコアが表示されません。UIを使ってスコアを表示しましょう。

Hierarchyで右クリックし、「UI」→「Text」またはTextMeshProのテキストを作成します。TextMeshProを使う場合は、必要に応じて初期設定を行います。

スクリプト側では、UIテキストを参照してスコアを更新します。

C#
using UnityEngine;
using TMPro;

public class PlayerController : MonoBehaviour
{
[SerializeField] private float moveSpeed = 5f;
[SerializeField] private TextMeshProUGUI scoreText;

private Rigidbody rb;
private int score = 0;

void Start()
{
rb = GetComponent<Rigidbody>();
UpdateScoreText();
}

void FixedUpdate()
{
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");

Vector3 movement = new Vector3(x, 0, z);
rb.AddForce(movement * moveSpeed);
}

void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Item"))
{
score++;
Destroy(other.gameObject);
UpdateScoreText();
}
}

void UpdateScoreText()
{
scoreText.text = "Score: " + score;
}
}

InspectorでscoreTextにUIテキストを設定するのを忘れないようにしましょう。

6-7. ゲームオーバー処理を実装する

ゲームオーバー処理は、条件を決めてif文で判定します。たとえば、プレイヤーがステージ外に落ちたらゲームオーバーにする場合は、Y座標をチェックします。

C#
[SerializeField] private GameObject gameOverPanel;
private bool isGameOver = false;

void Update()
{
if (transform.position.y < -5f && isGameOver == false)
{
GameOver();
}
}

void GameOver()
{
isGameOver = true;
gameOverPanel.SetActive(true);
Debug.Log("Game Over");
}

ゲームオーバー画面用のPanelを作成し、最初は非表示にしておきます。ゲームオーバーになったらSetActive(true)で表示します。

障害物に触れたらゲームオーバーにする場合は、OnTriggerEnterに処理を追加します。

C#
if (other.CompareTag("Obstacle"))
{
GameOver();
}

これで、プレイヤー移動、アイテム取得、スコア表示、ゲームオーバーまでを含む基本的なミニゲームが完成します。

7. Unity C#で初心者がつまずきやすいエラーと解決策

7-1. コンパイルエラーの読み方

コンパイルエラーは、C#の文法が間違っているときに発生します。UnityのConsoleウィンドウに赤いエラーとして表示されます。

初心者がよく見るエラーには、セミコロン忘れ、括弧の閉じ忘れ、変数名の打ち間違い、クラス名とファイル名の不一致などがあります。

たとえば、次のコードはセミコロンがないためエラーになります。

C#
int score = 0

正しくは次のように書きます。

C#
int score = 0;

エラーを読むときは、まずConsoleに表示されているファイル名と行番号を確認しましょう。エラー文すべてを理解できなくても、場所が分かれば原因を探しやすくなります。

7-2. NullReferenceExceptionの原因と直し方

Unity初心者がよく遭遇するエラーがNullReferenceExceptionです。これは、参照先が存在しない状態で変数やComponentを使おうとしたときに発生します。

たとえば、InspectorでUIテキストを設定し忘れた状態で次の処理を実行すると、NullReferenceExceptionが起きます。

C#
scoreText.text = "Score: " + score;

直し方は、まず何がnullなのかを確認することです。Inspectorで参照を設定しているか、GetComponentで正しく取得できているか、対象のGameObjectが存在しているかをチェックします。

不安な場合は、次のようにnullチェックを書くこともできます。

C#
if (scoreText != null)
{
scoreText.text = "Score: " + score;
}

ただし、nullチェックでエラーを隠すだけでは根本解決にならないこともあります。なぜnullになっているのかを確認する習慣をつけましょう。

7-3. スクリプトが動かないときの確認項目

C#スクリプトを書いたのに動かない場合は、次の点を確認します。

まず、スクリプトがGameObjectにアタッチされているか確認しましょう。Projectフォルダにスクリプトがあるだけでは実行されません。

次に、GameObjectがシーン上で有効になっているか確認します。チェックが外れていると、そのオブジェクトのスクリプトは動きません。

また、クラス名とファイル名が一致しているか、Consoleにコンパイルエラーが出ていないかも重要です。Unityでは、1つでもコンパイルエラーがあると他のスクリプトも正しく動かないことがあります。

StartやUpdateのスペルミスにも注意しましょう。startUpDateのように書くと、Unityのメソッドとして認識されません。

7-4. Inspectorで参照を設定し忘れた場合の対処

[SerializeField]publicで変数をInspectorに表示した場合、必要な参照を手動で設定する必要があります。

たとえば、次のような変数がある場合です。

C#
[SerializeField] private GameObject bulletPrefab;

このbulletPrefabには、InspectorからPrefabをドラッグ&ドロップして設定します。設定しないままInstantiateを実行すると、エラーになる可能性があります。

参照を忘れやすい場合は、Startで確認するコードを書いておくと便利です。

C#
void Start()
{
if (bulletPrefab == null)
{
Debug.LogError("bulletPrefabが設定されていません");
}
}

このようにしておくと、エラー原因を早く見つけられます。

7-5. UpdateとFixedUpdateの使い分けミス

UpdateとFixedUpdateの使い分けは、Unity C#初心者がつまずきやすいポイントです。

Updateは毎フレーム実行されるため、入力の取得や通常の状態確認に向いています。

C#
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
Debug.Log("ジャンプ");
}
}

FixedUpdateは物理演算のタイミングで実行されるため、Rigidbodyを使った移動や力を加える処理に向いています。

C#
void FixedUpdate()
{
rb.AddForce(Vector3.forward);
}

入力取得をFixedUpdateだけで行うと、タイミングによってはキー入力を取りこぼす場合があります。ジャンプのような処理では、Updateで入力を検知し、FixedUpdateで物理処理を行う設計にすることもあります。

7-6. 日本語エラーではなく英語エラーを検索するコツ

UnityやC#のエラーを検索するときは、日本語だけでなく英語のエラー文をそのまま検索するのがおすすめです。

たとえば、NullReferenceExceptionが出た場合は、「Unity NullReferenceException」と検索します。コンパイルエラーなら、エラー文の一部をコピーして検索すると解決策が見つかりやすいです。

また、「自分のコードが悪い」と考えるよりも、「どの変数がnullか」「どの行で止まっているか」「どのComponentが足りないか」と分解して確認することが大切です。

エラーはゲーム制作の一部です。エラーを読めるようになるほど、Unity C#の理解も深まります。

8. C# Unityを効率よく学ぶコツ

8-1. 文法だけを暗記せず小さく実装する

C#の文法を本だけで暗記しても、Unityで使えるようになるとは限りません。重要なのは、文法を小さな実装に結びつけることです。

たとえば、if文を学んだら「HPが0になったらゲームオーバー」を作る。変数を学んだら「スコアを保存する」を作る。Listを学んだら「複数の敵を管理する」を作る。

このように、1つの文法につき1つの小さなゲーム機能を作ると、知識が定着しやすくなります。

8-2. サンプルコードを写経したあとに改造する

初心者のうちは、サンプルコードを写して動かすだけでも効果があります。ただし、写しただけで終わると理解が浅くなりがちです。

コードが動いたら、少しだけ改造してみましょう。

移動速度を変える、ジャンプ力を変える、アイテムのスコアを10点にする、ゲームオーバー条件を変える、敵の出現位置をランダムにするなど、小さな変更で構いません。

改造すると、「この数値は何に影響しているのか」「このメソッドはいつ呼ばれるのか」が分かるようになります。

8-3. 公式ドキュメントの読み方

Unity C#を学ぶうえで、公式ドキュメントは重要です。ただし、初心者が最初からすべてを理解しようとすると難しく感じます。

最初は、使っているAPIのページだけを確認する程度で十分です。たとえば、Transform、Rigidbody、Collider、Input、Time、GameObject、Instantiate、Destroyなどです。

公式ドキュメントを見るときは、説明文だけでなくサンプルコードを確認しましょう。引数に何を渡すのか、戻り値があるのか、どのComponentで使うのかを見ると理解しやすくなります。

8-4. よく使うUnity C# APIから覚える

Unity C#には多くのAPIがありますが、初心者が最初に覚えるべきものは限られています。

特に重要なのは、transform.positionInput.GetKeyDownInput.GetAxisGetComponentInstantiateDestroyTime.deltaTimeOnTriggerEnterOnCollisionEnterSetActiveです。

これらを使えるようになるだけで、簡単なゲームなら十分作れます。

最初からすべてのAPIを覚える必要はありません。ゲームを作りながら、必要になった機能を調べて覚えるのが効率的です。

8-5. 2Dゲームと3Dゲームのどちらから始めるべきか

初心者が2Dと3Dのどちらから始めるべきかは、作りたいゲームによります。

2Dゲームは、横スクロールアクション、クリックゲーム、パズルゲームなどを作りたい人に向いています。画面構成が分かりやすく、素材も用意しやすいです。

3Dゲームは、玉転がし、簡単なアクション、探索ゲームなどを作りたい人に向いています。TransformやRigidbodyの動きが視覚的に分かりやすいメリットがあります。

C# Unityの基礎を学ぶ目的なら、どちらでも問題ありません。大切なのは、最初のゲームを小さく作ることです。

9. C# Unity入門後に作るべき練習ゲーム

9-1. 玉転がしゲーム

玉転がしゲームは、Unity C#初心者に非常におすすめです。プレイヤーとなる球をRigidbodyで動かし、ステージ上のアイテムを集めるだけでもゲームになります。

学べる内容は、Rigidbody、AddForce、Collider、Trigger、スコア管理、カメラ追従、UI表示などです。

実装がシンプルなので、C#の基礎とUnityの基本機能を同時に練習できます。

9-2. クリックゲーム

クリックゲームは、マウス入力とスコア管理を学ぶのに向いています。

画面上のボタンやオブジェクトをクリックするとスコアが増え、一定時間内にどれだけスコアを稼げるかを競うゲームにできます。

学べる内容は、Input、UI Button、TextMeshPro、タイマー、if文、メソッド分割などです。見た目はシンプルでも、ゲームループの基本を理解できます。

9-3. 2Dアクションゲーム

2Dアクションゲームでは、左右移動、ジャンプ、地面判定、敵との接触、ステージクリアなどを実装します。

学べる内容は、Rigidbody2D、Collider2D、OnCollisionEnter2D、アニメーション、カメラ追従、ステージ設計などです。

少し難易度は上がりますが、完成したときの達成感が大きく、Unity C#の理解も深まります。

9-4. シューティングゲーム

シューティングゲームでは、弾の生成、敵の出現、当たり判定、スコア加算、ゲームオーバー処理を学べます。

学べる内容は、Instantiate、Destroy、Prefab、ランダム生成、当たり判定、敵管理などです。

弾を撃つ処理は、Unity C#の実践練習に最適です。Prefabを使った開発にも慣れることができます。

9-5. パズルゲーム

パズルゲームは、ロジックを考える力を伸ばすのに向いています。

ブロックを並べる、同じ色を消す、マス目を管理する、条件を満たしたらクリアにするなど、C#の配列やListを使う機会が多くなります。

見た目の派手さよりも、内部処理の設計を学びたい人におすすめです。

9-6. 練習ゲームを完成させるためのチェックリスト

練習ゲームを完成させるには、最初から大きな目標を立てすぎないことが大切です。

まず、プレイヤーが操作できるか確認します。次に、ゲームの目的があるかを確認します。スコア、制限時間、クリア条件、ゲームオーバー条件のどれかを入れると、ゲームらしくなります。

さらに、タイトル画面、リトライ機能、効果音、簡単な演出を加えると完成度が上がります。

途中で新しい機能を増やしすぎると完成しにくくなるため、最初は「1画面で遊べる小さなゲーム」を目指しましょう。

10. C# Unity入門に関するよくある質問

10-1. C#を先に全部学んでからUnityを始めるべきか

C#を先に全部学ぶ必要はありません。Unityでゲームを作りたいなら、Unityで使うC#から学ぶほうが効率的です。

もちろん、変数、if文、for文、メソッド、クラスなどの基礎は必要です。しかし、C#の高度な機能をすべて理解してからでないとUnityを始められないわけではありません。

最初は、Unityでよく使う文法をゲーム制作と一緒に覚えましょう。

10-2. プログラミング未経験でもUnity C#は学べるか

プログラミング未経験でもUnity C#は学べます。ただし、最初は専門用語が多く感じるかもしれません。

大切なのは、いきなり大作ゲームを作ろうとしないことです。まずは、オブジェクトを動かす、キー入力を受け取る、アイテムを消す、スコアを増やすといった小さな処理から始めましょう。

小さな成功体験を積み重ねることで、C#の文法もUnityの操作も自然に理解できるようになります。

10-3. Unity C#の習得にかかる期間

Unity C#の習得期間は、目標によって変わります。

簡単なミニゲームを作るだけなら、集中して学べば数週間でも形にできます。2Dアクションやシューティングなど、複数の機能を組み合わせたゲームなら、数か月ほどかけて学ぶのが現実的です。

重要なのは、学習時間の長さよりも、実際に手を動かして完成させることです。1つでもゲームを完成させると、次に作るゲームの理解が大きく進みます。

10-4. JavaやJavaScript経験者が注意すべき違い

Java経験者は、C#の文法に近い部分が多いため比較的入りやすいです。ただし、Unity特有のMonoBehaviour、Start、Update、Inspector、GameObject、Componentの考え方に慣れる必要があります。

JavaScript経験者は、型の扱いに注意しましょう。C#では、変数の型を明確に指定します。

C#
int score = 0;
float speed = 5f;
bool isClear = false;

また、Unity C#ではオブジェクトがシーン上に存在し、Componentを通じて操作するという考え方が重要です。Web開発とは異なる部分なので、Unityの仕組みとして理解しましょう。

10-5. UnityのVisual ScriptingとC#はどちらを選ぶべきか

Unityには、コードを書かずに処理を組めるVisual Scriptingもあります。プログラミング未経験者が処理の流れを理解するには便利です。

ただし、長期的にゲーム制作を学ぶならC#を覚えることをおすすめします。C#を使えると、複雑な処理を書きやすく、サンプルコードや解説記事も活用しやすくなります。

最初にVisual Scriptingで考え方をつかみ、その後C#に移行する方法もあります。最短で実装力をつけたいなら、簡単なC#から始めるのがよいでしょう。

10-6. スマホゲーム制作にもC# Unityは使えるか

C# Unityはスマホゲーム制作にも使えます。UnityはPCゲームだけでなく、スマホ向けゲームの開発にも利用できます。

スマホゲームでは、タッチ入力、画面サイズ対応、パフォーマンス最適化、ビルド設定などが重要になります。基礎部分はPC向けゲームと同じで、プレイヤー操作、当たり判定、スコア管理、UI表示などにはC#を使います。

まずはPC上で簡単なゲームを完成させ、その後スマホ向けの操作やビルドに挑戦するとスムーズです。

まとめ

C# Unity入門で大切なのは、C#の文法をすべて暗記することではなく、Unityでゲームを作るために必要な部分から実装して覚えることです。

最初に理解すべきなのは、Unity Editorの基本操作、C#スクリプトの作成、MonoBehaviour、Start、Update、GameObject、Componentの関係です。そのうえで、変数、if文、for文、メソッド、配列、List、クラスなどのC#基礎文法を学びましょう。

実装面では、Transform、Input、Rigidbody、Collider、Instantiate、Destroy、Time.deltaTimeを使えるようになると、簡単なゲームを作れるようになります。

初心者は、玉転がしゲームやクリックゲームのような小さな作品から始めるのがおすすめです。小さく作り、動かし、エラーを直し、少し改造する。この繰り返しが、Unity C#を最短で身につける近道です。

「csharp unity」で調べ始めた段階では分からないことが多くても、1つずつ実装していけば必ず理解は深まります。まずは小さなゲームを1つ完成させることを目標に、C# Unityの基礎を実践しながら学んでいきましょう。