「ただ、キャラクターを動かしたかっただけなのに」
私が初めてゲームを作ろうと思ったのは、もう15年以上前のことです。当時はまだUnityなんて便利なものはなく、DirectXという恐ろしく難解なライブラリと格闘していました。黒い画面に白い三角形を一つ表示させるためだけに、3日間もコードを書き続け、エラーと睨めっこした記憶があります。
時代は変わり、今はUnityがあります。画面上にキャラクターをドラッグ&ドロップすれば、とりあえず表示はされる。物理演算をオンにすれば、重力で落下もしてくれる。
「なんだ、ゲーム作りなんて簡単じゃん」
そう思ったのも束の間、多くの初心者が巨大な壁にぶち当たります。
「C#スクリプト」という壁です。
「スペースキーを押したらジャンプさせたい」
ただそれだけのことが、コードを書かないとできない。ネットで検索してコピペしてみたけど、動かない。エラーメッセージは英語で意味不明。数式のような記号の羅列を見て、そっとUnityを閉じてしまう……。
そんな経験、ありませんか?
私がメンターとして担当している受講生の方々も、9割以上がこの「プログラミングの壁」で一度心を折られます。3Dモデルを作ったり、ステージを配置したりするのは楽しい。でも、コードを書く段になると急に手が止まるのです。
しかし、断言します。
ゲーム開発に必要なC#の知識は、実はそんなに多くありません。
分厚い専門書に書かれていることの半分以上は、最初のうちは知らなくてもゲームは作れます。重要なのは「文法を暗記すること」ではなく、「ゲームの中でどう使うか」を理解することです。
現役のエンジニアであり、数多くの「挫折しかけた初心者」を救ってきた私が、ゲーム開発(特にUnity)に必要なC#の基礎を、実戦形式で徹底的に解説します。教科書的な説明は極力省き、「現場でどう使うか」「どこでハマるか」にフォーカスしました。
これを読み終える頃には、あなたの目には、あの無機質なコードの羅列が「キャラクターへの指令書」として鮮明に見えているはずです。さあ、エディタを開く準備はいいですか?

なぜゲーム開発に「C#」なのか?
そもそも、なぜUnityはC#を採用しているのでしょうか。
プログラミング言語にはPythonやJavaScript、C++など様々なものがあります。その中でC#が選ばれている理由を知ることは、学習のモチベーション維持に繋がります。
「読みやすさ」と「速さ」のいいとこ取り
ゲームは処理速度が命です。毎秒60回(60fps)画面を更新するために、膨大な計算を瞬時に行う必要があります。その点ではC++という言語が最強なのですが、これは人間が読み書きするにはあまりにも難解で、メモリ管理などを自分で行う必要があります(ここで多くの先人たちが散っていきました)。
一方で、Pythonなどは書きやすいですが、実行速度が少し遅い。
C#はその中間に位置します。Javaに似た文法で人間にも読みやすく、メモリ管理は自動(ガベージコレクション)でやってくれるのに、実行速度も十分に速い。
Unity TechnologiesがC#をメイン言語に据えたのは、この「開発効率とパフォーマンスのバランス」がゲーム開発に最適だったからです。
膨大な「資産」が使える
UnityでC#を使う最大のメリットは、世界中の開発者が蓄積してきた「知見」と「ライブラリ」が使えることです。
「RPGのインベントリシステムを作りたい」「オンライン対戦を実装したい」
そう思った時、ゼロから作る必要はありません。誰かがC#で書いたコードが、アセットストアやGitHubに転がっています。C#を読めるようになれば、巨人の肩に乗って、自分の作りたいものを最短で実現できるのです。
第1章:変数と型 ~ゲームの世界を「数字」で表現する~
ここから具体的な文法の話に入りますが、教科書のように「intとは整数型です」なんて退屈な説明はしません。ゲーム開発の視点で解説します。
変数は「ステータス画面」そのもの
ゲームを作るとは、突き詰めれば「データを変化させること」です。
HPが減る、経験値が増える、座標が変わる、フラグが立つ。
これらのデータを保存しておく「箱」が変数です。
初心者が最初につまずくのが「型(Type)」の概念です。「なんでいちいち int とか float とか指定しなきゃいけないの? 全部 var じゃダメなの?」と思いますよね。
でも、ゲームにおいて「型」は、そのデータが何者であるかを定義する重要な要素です。
- int(整数): HP、攻撃力、所持金、アイテムの個数。
- 1.5個のアイテムなんて存在しませんよね。だから整数です。
- float(浮動小数点数): 座標、移動速度、タイマー。
- ゲームの世界では「X座標 10.5」のような細かい位置調整が必要です。Unityで座標や回転を扱うときは、ほぼ100%この
floatを使います。数字の最後にfをつけるのがお約束です(例:3.5f)。
- ゲームの世界では「X座標 10.5」のような細かい位置調整が必要です。Unityで座標や回転を扱うときは、ほぼ100%この
- string(文字列): キャラクターの名前、セリフ、メッセージ。
"勇者"のようにダブルクォーテーションで囲みます。
- bool(真偽値): フラグ。生存しているか(IsAlive)、地面に足がついているか(IsGrounded)。
true(真)かfalse(偽)のどちらかしか入りません。これがゲームの進行管理の要になります。
現場のリアル:publicとprivateの使い分け
UnityでC#を書くとき、変数の前に public や private をつけます。これを「アクセス修飾子」と言いますが、初心者はとりあえず全部 public にしがちです。
public int hp = 100;
こう書くと、Unityのエディタ上(Inspectorウィンドウ)で、ゲーム実行中にHPの数値を自由にいじれるようになります。デバッグ調整にめちゃくちゃ便利です。
しかし、現場レベルの話をすると、何でもかんでも public にするのは危険です。他のスクリプトから勝手にHPを書き換えられてしまい、バグの原因になるからです。
プロの現場では、[SerializeField] private という書き方をよく使います。
これは「他のスクリプトからは触らせない(private)けど、Unityのエディタ上からは調整したい(SerializeField)」という、わがままを叶える魔法の呪文です。
[SerializeField] private int hp = 100; // これが現場の推奨スタイル
最初は public でも動きますが、慣れてきたらこの書き方を覚えておくと「お、こいつ出来るな」と思われます。

第2章:条件分岐と繰り返し ~ゲームの「ルール」を作る~
変数があるだけでは、ただのデータの羅列です。そこに「ルール」を与えるのが制御構文です。
if文:すべてのゲームロジックの基本
「もし~なら、こうする」。これがなければゲームは成立しません。
- もし(HPが0になったら)→ ゲームオーバー画面を出す
- もし(ボタンが押されたら)→ ジャンプする
- もし(敵との距離が近かったら)→ 攻撃する
if (hp <= 0)
{
Die(); // 死ぬ処理
}
else if (hp < 20)
{
ShowRedScreen(); // 画面を赤くする(ピンチ演出)
}
else
{
// 何もしない、あるいは通常状態
}
初心者がハマるポイントとして、「比較演算子」があります。
「等しい」は = ではなく == です。= は「代入(右のものを左に入れる)」という意味になってしまいます。if (hp = 0) と書いてしまい、HPを無理やり0にしてしまうバグは、全人類が一度は通る道です。
for文とforeach文:敵を100体出す魔法
「敵を1体出現させる」コードは書けた。でも、100体出したい時はどうするか?
同じコードを100行コピペしますか? しませんよね。そこでループ処理の出番です。
// 100回繰り返す
for (int i = 0; i < 100; i++)
{
SpawnEnemy(); // 敵を出す処理
}
Unity開発では、配列やリストと一緒に使う foreach も頻出です。
例えば、「画面内にいる全ての敵にダメージを与える」といった処理です。
// enemiesというリストに入っている全ての敵に対して処理をする
foreach (var enemy in enemies)
{
enemy.TakeDamage(10);
}
これを使いこなせると、「弾幕シューティング」や「大量のゾンビが襲ってくるゲーム」が作れるようになります。コンピュータの得意技である「単純作業の高速繰り返し」を武器にするのです。
第3章:メソッド(関数) ~処理をまとめる「魔法の呪文」~
コードが長くなってくると、どこで何をしているのか分からなくなります。スパゲッティコードの誕生です。
これを防ぐために、一連の処理をひとまとめにして名前をつけるのがメソッド(関数)です。
攻撃処理をパッケージ化する
例えば、攻撃ボタンを押した時の処理が「アニメーション再生」「音を鳴らす」「当たり判定を出す」「スタミナを減らす」の4つだったとします。これを毎回書くのは大変です。
void Attack()
{
PlayAnimation("Attack");
PlaySound("SwordSlash");
EnableHitBox();
stamina -= 10;
}
こうやって Attack というメソッドを作っておけば、あとは必要な場所で Attack(); と唱えるだけで、これら全ての処理が実行されます。
メソッドを作ることは、「自分だけの命令文を作る」ことと同じです。
引数と戻り値:情報のキャッチボール
メソッドはただ命令するだけでなく、情報を渡したり、結果を受け取ったりできます。
- 引数(ひきすう): メソッドに渡す材料。
Attack(50);なら「攻撃力50で攻撃しろ」という意味になります。
- 戻り値(もどりち): メソッドから返ってくる結果。
bool isHit = CheckHit();なら「攻撃が当たったかどうか(true/false)」を受け取ります。
初心者のうちは void(戻り値なし)ばかり使いがちですが、計算結果を返すメソッドを作れるようになると、コードの再利用性がグンと上がります。
例えば「レベルに応じた必要経験値を計算するメソッド」を作っておけば、UI表示でもレベルアップ判定でも使い回せますよね。

第4章:クラスとオブジェクト指向 ~量産と管理の技術~
ここが最大の難所です。多くのチャレンジャーがここで脱落します。
「クラスって何? インスタンスって何?」
専門用語を使わずに説明しましょう。
クラスは「設計図」、インスタンスは「実体」
たい焼きで例えるのが有名ですが、ゲーム開発なら「モンスターのデータ」で考えると分かりやすいです。
「スライム」というモンスターを作りたいとします。スライムにはHPがあり、攻撃力があり、体当たりしてきます。
この「スライムの仕様書」にあたるのがクラスです。
public class Slime
{
int hp = 10;
int attack = 3;
void JumpAttack()
{
// 飛び跳ねて攻撃する処理
}
}
しかし、このコードを書いただけでは、ゲーム画面には何も現れません。あくまで「仕様書(設計図)」を書いただけだからです。
この設計図を元に、メモリ上に生み出された「実際のスライムA」「スライムB」のことをインスタンス(実体)と呼びます。
Unityの場合、この概念が少し特殊で視覚的です。
C#スクリプト(Slime.cs)を書くことが「クラスを作る」ことにあたり、それをGameObjectにアタッチしたり、プレハブとしてシーンに配置したりしたものが「インスタンス」になります。
「スクリプトを書いたのに動かない!」という初心者の悩みは、大抵「設計図を書いただけで、実体をシーンに置いていない(アタッチしていない)」ことが原因です。
コンポーネント指向:Unityならではの流儀
一般的なC#のオブジェクト指向と、Unityの流儀には少し違いがあります。
Unityは「コンポーネント指向」という考え方を採用しています。
これは、「空っぽのGameObject」に、「機能(コンポーネント)」をペタペタ貼り付けていくことでキャラクターを作る方法です。
- 「位置情報」が必要なら
Transformコンポーネント - 「絵」が必要なら
SpriteRendererコンポーネント - 「物理挙動」が必要なら
Rigidbodyコンポーネント - 「独自の動き」が必要なら、あなたが書いた
C#スクリプト
あなたが書くC#スクリプトも、あくまで「一つの部品(コンポーネント)」として扱われます。
だからこそ、Unityのスクリプトは必ず MonoBehaviour というクラスを継承(継ぎ足し)して作られるのです。
「MonoBehaviour って何?」と深く考える必要はありません。「Unityの部品として動くための基本機能セット」だと思ってください。これがないと、GameObjectに貼り付けることができません。

第5章:Unity特有の「お約束」メソッド
Unityでゲームを作る際、避けて通れない特別なメソッドたちがいます。これらは自分で呼ぶのではなく、Unity側が「特定のタイミング」で勝手に呼んでくれるものです。これをイベント関数と呼びます。
Start() と Update()
スクリプトを作ると最初から書かれているこの二人。
- Start(): ゲームが始まった瞬間(またはそのオブジェクトが生まれた瞬間)に、1回だけ呼ばれます。
- HPの初期化、アイテムの装備、コンポーネントの取得など、「準備運動」に使います。
- Update(): ゲーム中、1フレームごとに毎回呼ばれ続けます。
- キー入力の検知、移動処理、タイマーのカウントなど、「動き続けるもの」はここに書きます。
初心者がよくやるミスが、「1回だけでいい処理(例:BGMの再生開始)」を Update() に書いてしまうこと。すると、1秒間に60回も「再生しろ!再生しろ!」と命令され、音がバグったり処理落ちしたりします。
「これはずっと監視すべきことか? 最初だけでいいことか?」を常に意識してください。
GetComponent():隣の部品を借りる
スクリプトから、同じオブジェクトについている別のコンポーネント(例:物理演算をするRigidbody)を操りたい時、どうすればいいでしょうか。
そこで使うのが GetComponent<型名>() です。
Rigidbody2D rb;
void Start()
{
// 同じオブジェクトについているRigidbody2Dを探してきて、変数rbに入れる
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
// rbを使って上に力を加える(ジャンプ)
rb.AddForce(Vector2.up * 10);
}
これも初心者のバグの温床です。GetComponent は意外と重い処理なので、Update() の中で毎回呼んではいけません。Start() で一度だけ呼んで変数にキャッシュ(保存)しておく。これが現場の鉄則です。
第6章:実践!バグとエラーとの付き合い方
コードを書けば、必ずエラーが出ます。ベテランでも出ます。
エラーが出た時、初心者は「才能がない」と落ち込みますが、プロは「ヒントが出た」と喜びます(嘘です、舌打ちはします)。
赤い波線は「文法ミス」
エディタ上で出る赤い波線は、コンパイルエラー。つまり「C#の言葉として間違っているよ」という指摘です。
;(セミコロン)の付け忘れ{ }(波括弧)の閉じ忘れ- スペルミス(
Startをstartと書くなど)
これらは実行前に直せます。Visual StudioなどのIDE(統合開発環境)が教えてくれるヒントをよく読みましょう。
Consoleの赤い文字は「実行時エラー」
UnityのConsoleウィンドウに出る赤いエラー。これは「文法は合ってるけど、実行中に矛盾が起きたよ」という合図です。
代表的なのが NullReferenceException。通称「ぬるぽ」。
「空っぽ(Null)の箱の中身を使おうとしましたよ」というエラーです。
GetComponentで取得しようとしたコンポーネントがついていなかった。- Inspectorで設定すべき変数が、空欄のままだった。
このエラーが出たら、まずは「どの変数が空っぽなのか」を疑ってください。Debug.Log(変数名); を仕込んで、中身を確認するのが調査の第一歩です。
ログ出力こそ最強のデバッグ
Debug.Log("ここを通った");
これをコードのあちこちに仕込むこと。これが最強のデバッグ術です。
if文の中にこれを入れて、ログが出なければ、そもそも条件分岐に入れていないことが分かります。
プログラミングは推測でやってはいけません。ログという証拠を見て、事実に基づいて修正するのです。

第7章:学習を続けるためのマインドセット
C#の基礎を一通り覚えたとしても、ゲーム作りにはまだまだ壁があります。
「作りたい機能の実装方法がわからない」
「エラーがどうしても消えない」
そんな時、どうすればいいのでしょうか。
「リファレンス」を恐れない
Unity公式のスクリプトリファレンスは、最初は呪文のように見えるかもしれません。でも、あそこには全ての正解が書いてあります。
ネットの技術記事(QiitaやZenn)は分かりやすいですが、情報が古かったり間違っていたりすることもあります。
最終的に信頼できるのは公式ドキュメントです。「Unity Rigidbody」などで検索し、公式の説明を読む癖をつけましょう。最初は意味がわからなくても、用語に慣れるだけで成長します。
100点を目指さない
初心者が挫折する最大の理由は「理想が高すぎること」です。
最初から市販のRPGのようなものを作ろうとしてはいけません。
まずは「四角い箱が動くだけ」でいいんです。「クリックしたら音が鳴るだけ」でいいんです。
小さな成功体験を積み重ねてください。クソゲー上等です。動けば勝ちです。
FAQ:よくある質問
Q. 数学が苦手ですが、ゲームプログラミングはできますか?
A. できます。高校レベルの三角関数(サイン・コサイン)やベクトルが分かると便利ですが、Unityにはそれを肩代わりしてくれる便利な関数がたくさんあります。例えば「敵の方を向く」処理も、数学を使わずに Transform.LookAt() 一発で済みます。必要になった時に調べれば十分です。
Q. 独学とスクール、どっちがいいですか?
A. 独学でも可能ですが、エラーで詰まった時の「時間のロス」が膨大です。何日も悩んだエラーが、メンターに見せたら3秒で解決した、なんてことは日常茶飯事です。時間を金で買うつもりならスクール、時間をかけてでも自力で解決する力をつけたいなら独学、という選び方が良いでしょう。
Q. C#以外の言語(JavaScriptなど)じゃダメですか?
A. 昔のUnityはJavaScript(UnityScript)も使えましたが、今は廃止されました。UnityをやるならC#一択です。他の言語に逃げ道はありませんが、逆に言えばC#さえ覚えればOKということです。
おわりに:あなたのコードが世界を作る
ここまで、ゲーム開発におけるC#の基礎について解説してきました。
変数、if文、メソッド、クラス…。最初は無機質な記号に見えたものが、少しは意味のある言葉に見えてきたでしょうか。
プログラミングは、コンピュータへの手紙です。
「右へ動いて」「ぶつかったら消えて」「スコアを増やして」
あなたのその想いを、C#という言葉で伝えるだけです。
私も最初は、if文の書き方すら分かりませんでした。
それでも、拙いコードを書き継いで、初めて自分のキャラクターが画面の中でジャンプした時。あの瞬間の感動は、何物にも代えがたいものでした。
まるで、自分の中に神様が宿ったような、世界を創造したような感覚。
あなたにも、その感覚を味わってほしい。
エラーが出ても諦めないでください。それは、あなたのゲームが完成に近づいている証拠です。
今日覚えた知識を武器に、まずは1行、コードを書いてみてください。
その1行が、あなたの想像する壮大な世界の、最初のレンガになります。
さあ、Unityを開きましょう。あなたの冒険は、ここから始まります。

あなたの書いたコードが、誰かの心を動かす日が来ることを、心から信じています。
まずは Debug.Log("Hello World!"); から始めてみましょう。
健闘を祈ります!
