UnityでC#スクリプトを作ると、必ずpublic class MyScript : MonoBehaviourという一文が付いてきます。「おまじない」として何となく書いているけれど、これが何者なのかは説明できない——そんな方は意外と多いのではないでしょうか。
MonoBehaviourは、UnityのAPIと自作スクリプトを繋ぐ「基底クラス」です。これを継承(:の右側に記述)するだけで、スクリプトはゲームオブジェクトにコンポーネントとして追加できるようになり、UpdateやStartといったイベントを受け取り、transformやgameObjectといった便利なプロパティが使えるようになります。
この記事でわかること
MonoBehaviourを継承すると何ができるようになるのかtransform・gameObject・GetComponent<T>()の使い方Instantiate/Destroyによるオブジェクトの生成と破棄- 「
newできない」「Invokeは文字列指定」などのつまずきポイント
MonoBehaviourの役割
MonoBehaviourを継承する主なメリットは以下の通りです。
- コンポーネント化: 作成したスクリプトをゲームオブジェクトのコンポーネントとしてアタッチできるようになります。これにより、オブジェクトに振る舞いを追加できます。
- ライフサイクルイベントの受信:
Awake,Start,Updateなど、Unityが定義した特定のタイミングで自動的に呼び出されるイベント関数を使用できます。 - 主要プロパティへのアクセス: スクリプトがアタッチされているゲームオブジェクト自身や、そのTransformコンポーネントなどに簡単にアクセスできます。
- コルーチンの実行:
StartCoroutineメソッドを使って、「3秒待ってから実行」「数フレームに分けて少しずつ処理」のような 時間をまたぐ処理 を書けます。別スレッドで動くわけではなく、 メインスレッド上で処理を分割・待機する仕組み です(詳しくは コルーチンの記事 へ)。
MonoBehaviourの立ち位置を図にすると、「Unityエンジンと自作スクリプトを繋ぐ架け橋」というイメージになります。継承した瞬間から、Unity側のイベント(AwakeやUpdateなど)が自分のスクリプトに届くようになるわけです。

もしMonoBehaviourを継承しないただのC#クラス(POCO - Plain Old C# Object と呼ばれることもあります)を作成した場合、それはUnityのゲームオブジェクトにアタッチできず、ライフサイクルイベントも受け取れません。そうしたクラスは、データ保持専門のクラスや、計算処理専門のクラスとしてMonoBehaviourから呼び出して使うことになります。
「切り出す」感覚を小さな例で見てみましょう。ダメージ計算はUnityの機能を何も使わないので、普通のC#クラスにできます。
// MonoBehaviourを継承しない、計算専門の普通のC#クラス
public class DamageCalculator
{
public int Calculate(int attack, int defense)
{
int damage = attack - defense;
return damage < 1 ? 1 : damage; // 最低でも1ダメージ
}
}
これをMonoBehaviour側から呼び出します。
using UnityEngine;
public class Enemy : MonoBehaviour
{
// 普通のC#クラスは、MonoBehaviourと違ってnewで作れる
private DamageCalculator calculator = new DamageCalculator();
public void OnAttacked(int attack, int defense)
{
int damage = calculator.Calculate(attack, defense);
Debug.Log($"受けたダメージ: {damage}");
}
}
こうしておくと、ダメージ計算のロジックはシーンにもGameObjectにも依存せず、テストや使い回しがしやすくなります。 「Unityと対話する 部分はMonoBehaviour、純粋な計算やデータは普通のクラス」 という分担は、上達してからも効き続ける基本です。
補足:
MonoBehaviourを継承したクラスは、new MyScript()のようにnewでインスタンス化することはできません 。必ずAddComponent<MyScript>()でゲームオブジェクトに追加するか、エディタ上でアタッチして生成します。これはつまずきやすいポイントなので覚えておきましょう。
主要なプロパティとメソッド
MonoBehaviourを継承したスクリプト内では、多くの便利なプロパティやメソッドを直接呼び出すことができます。ポイントは、 スクリプトは「自分がアタッチされている器(GameObject)」を起点に、器自身や同じ器の中の部品へ直接アクセスできる ということです。

ここでは特に頻繁に使うものを紹介します。
transform
スクリプトがアタッチされているゲームオブジェクトの Transformコンポーネント への参照を返します。オブジェクトの位置、回転、スケールを操作する際に頻繁に使用します。これ はGetComponent<Transform>()のショートカットであり、非常によく使われるため特別に用意されています。
using UnityEngine;
public class PositionChanger : MonoBehaviour
{
void Start()
{
// transformプロパティを使って、オブジェクトのY座標を5に設定する
transform.position = new Vector3(0, 5, 0);
}
}
gameObject
スクリプトがアタッチされている ゲームオブジェクト自身 への参照を返します。オブジェクトを非アクティブにしたり、他のコンポーネントを取得したりする際の起点となります。
using UnityEngine;
public class ObjectController : MonoBehaviour
{
void Start()
{
// 5秒後にこのゲームオブジェクトを非アクティブにする
Invoke("DeactivateObject", 5f);
}
void DeactivateObject()
{
// gameObjectプロパティを使って、自身を非アクティブにする
gameObject.SetActive(false);
}
}
補足: この例で使っている
Invokeは、メソッド名を 文字列 で指定する仕組みです。手軽な反面、タイプミスをコンパイル時に検出できず、メソッド名を変更(リネーム)した際にも追従してくれません。本格的な遅延処理には、後述のコルーチンやasync/awaitを使う方が安全です。
GetComponent<T>()
同じゲームオブジェクトにアタッチされている、指定した型Tのコンポーネントへの参照を取得します。Unityのコンポーネント指向設計において、他のコンポーネントと連携するための最も基本的なメソッドです。
using UnityEngine;
public class PlayerHealth : MonoBehaviour
{
private Rigidbody rb;
void Start()
{
// 同じGameObjectにアタッチされているRigidbodyコンポーネントを取得
rb = GetComponent<Rigidbody>();
if (rb != null)
{
// Rigidbodyが見つかったら、その質量を10に設定
rb.mass = 10f;
}
}
}
パフォーマンスのヒント: GetComponent<T>()の呼び出しにはコストがあります。1回や数回なら気にする必要はありませんが、Update()のような毎フレーム呼ばれる場所で繰り返し呼ぶと積み重なります。何度も使う参照はAwake()やStart()で一度だけ取得して変数に保存(キャッシュ)しておくのがベストプラクティスです。
Instantiate() と Destroy()
Instantiate(original):original(Prefabや既存のゲームオブジェクト)のクローンをシーンに生成します。敵や弾、エフェクトなどを動的に生成する際に使用します。Destroy(obj):objで指定したゲームオブジェクト、コンポーネント、またはアセットを破棄します。不要になったオブジェクトをシーンから削除する際に使用します。

using UnityEngine;
public class BulletSpawner : MonoBehaviour
{
public GameObject bulletPrefab;
void Update()
{
// スペースキーが押されたら
if (Input.GetKeyDown(KeyCode.Space))
{
// Prefabから弾を生成する
GameObject newBullet = Instantiate(bulletPrefab, transform.position, Quaternion.identity);
// 3秒後にその弾を破棄する
Destroy(newBullet, 3f);
}
}
}
おまけ:先に知っておくと良いこと
この記事の内容を使い始めると、いずれ次のような「その先の話」に出会います。今すぐ理解する必要はありませんが、存在だけ知っておくと、後で困ったときの引き出しになります。
Instantiate/Destroyは実は重い処理: 弾丸やエフェクトのように大量の生成・破棄を繰り返すと、カクつき(GCスパイク)の原因になります。実際の制作では、生成済みのオブジェクトを使い回す オブジェクトプーリング という手法で軽量化するのが定番です。詳しくは オブジェクトプーリングの記事 で解説しています。- イベント関数が呼ばれる順序には厳密なルールがある:
AwakeやUpdateが「いつ・どの順で」呼ばれるかを理解すると、初期化まわりのバグの大半を防げま す。ライフサイクルの記事 にまとめています。 - なんでもMonoBehaviourにしない設計もある: データだけを扱うクラスは、
MonoBehaviourを継承しない普通のC#クラスや ScriptableObject にすると、シーンに依存しないすっきりした設計になります。ScriptableObjectの記事 が参考になります。
まとめ
MonoBehaviourは、Unityにおけるスクリプティングの根幹をなすクラスです。このクラスを継承することで、私たちの書いたC#コードは初めてUnityの世界と対話し、ゲームオブジェクトに命を吹き込むことができます。
MonoBehaviourはUnityとスクリプトを繋ぐ架け橋。- 継承することで、コンポーネントとして振る舞い、ライフサイクルイベントを受け取れる。
transform,gameObject,GetComponent<T>()などの便利なプロパティやメソッドが使えるようになる。
Unityでの開発は、このMonoBehaviourをいかにうまく使いこなすかにかかっていると言っても過言ではありません。まずは今回紹介した基本的なプロパティやメソッドに慣れ親しむことから始めましょう。