この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:5
ページ更新者:atom
更新日時:2026-06-11 07:10:02

タイトル: ゲームオブジェクト(Game Object)
SEOタイトル: Unity GameObject (ゲームオブジェクト) 完全ガイド

この記事の要点
  • GameObject: Unity の Hierarchy に存在する全要素の基本クラス。プレイヤー / 敵 / カメラ / ライト / UI 全てが GameObject
  • Component の入れ物: GameObject 自体は座標 (Transform) だけ持ち、機能は Component で追加
  • 必須 Component: Transform (削除不可)。その他 Mesh / Collider / Rigidbody / Script は自由に Add
  • Hierarchy 階層: 親子関係で座標を継承、transform.SetParent() で動的変更
  • API: Instantiate / Destroy / SetActive / Find / GetComponent が頻出

GameObject とは

Unity の GameObject は、Hierarchy ウィンドウに表示される全てのオブジェクトの基底クラスです。プレイヤー、敵、カメラ、ライト、UI ボタン、効果音発生源、空のゲームオブジェクト — 全て GameObject インスタンスです。

GameObject 単体は空の箱に過ぎません。座標 (Transform) を持ち、そこに Component を追加することで初めて意味を持ちます。

GameObject と Component の関係

GameObject "Player"
├── Transform              ← 必須。位置・回転・スケール
├── MeshFilter             ← 描画する形状
├── MeshRenderer           ← 描画するマテリアル
├── BoxCollider            ← 当たり判定
├── Rigidbody              ← 物理演算
├── AudioSource            ← 音再生
├── Animator               ← アニメーション
└── PlayerController (Script) ← 自作スクリプト

Unity はComposition over Inheritanceのフィロソフィー: 1 つの巨大なクラスを継承するのではなく、機能ごとの小さな Component を組み合わせて GameObject を作ります。

Transform は必須 Component

GameObject から削除できない唯一の Component。3D 空間における位置 / 回転 / スケールを持ちます:

// 位置・回転・スケール
transform.position = new Vector3(0, 1, 0);
transform.rotation = Quaternion.Euler(0, 90, 0);
transform.localScale = new Vector3(2, 2, 2);

// ローカル座標 (親に対する相対位置)
transform.localPosition = Vector3.zero;
transform.localRotation = Quaternion.identity;

// 親子関係
transform.SetParent(otherGameObject.transform);   // 親を変える
transform.parent = otherGameObject.transform;     // 同上 (旧 API)
transform.DetachChildren();                       // 全子を切り離す

// 子オブジェクトのアクセス
foreach (Transform child in transform) { ... }
Transform t = transform.GetChild(0);
Transform t = transform.Find("Sword");           // 名前検索

// 移動 (時間と無関係)
transform.Translate(Vector3.forward * 0.1f);

// Time.deltaTime と組み合わせて FPS 非依存
transform.position += Vector3.forward * speed * Time.deltaTime;

GameObject の生成と削除

// Prefab から複製生成
public GameObject enemyPrefab;
GameObject enemy = Instantiate(enemyPrefab, spawnPos, Quaternion.identity);

// 親子付きで生成
Instantiate(enemyPrefab, parentTransform);

// 動的に空のオブジェクト生成
GameObject go = new GameObject("MyObject");
go.AddComponent<Rigidbody>();
go.AddComponent<BoxCollider>();
go.tag = "Enemy";
go.layer = LayerMask.NameToLayer("Enemy");

// 削除
Destroy(enemy);            // 次フレームで削除
Destroy(enemy, 5f);        // 5 秒後に削除
DestroyImmediate(enemy);   // 即削除 (Editor のみ推奨)

// シーンを跨いで生存させる
DontDestroyOnLoad(go);

GameObject の有効化 / 無効化

削除せず非表示にする定番手段。Component の処理も止まる:

// 無効化 (子も含めて Update / Render が止まる)
gameObject.SetActive(false);

// 再有効化
gameObject.SetActive(true);

// 状態確認
if (gameObject.activeSelf) { ... }     // 自身の active 状態
if (gameObject.activeInHierarchy) { ... } // 親も含めた最終状態

// 個別 Component だけ無効化
GetComponent<Renderer>().enabled = false;     // 見えなくするだけ
GetComponent<Collider>().enabled = false;     // 当たり判定だけ消す
GetComponent<MonoBehaviour>().enabled = false; // Update を止める

Component のアクセスと操作

// Component を取得
Rigidbody rb = GetComponent<Rigidbody>();
if (rb != null) rb.AddForce(Vector3.up * 10);

// TryGetComponent (null チェック不要、Unity 2019.2+ で高速)
if (TryGetComponent<Rigidbody>(out var rb)) {
    rb.AddForce(Vector3.up * 10);
}

// 子から検索
Animator anim = GetComponentInChildren<Animator>();

// 親から検索
Canvas canvas = GetComponentInParent<Canvas>();

// 全 Component
Component[] all = GetComponents<Component>();

// 動的追加 / 削除
Rigidbody added = gameObject.AddComponent<Rigidbody>();
Destroy(GetComponent<BoxCollider>());

Tag と Layer

大量の GameObject から特定種類を識別するための仕組み。Tag は文字列、Layer はビット (32 種類まで):

// Tag (文字列分類)
gameObject.tag = "Enemy";
if (other.CompareTag("Player")) { ... }      // 比較は CompareTag が高速

// Layer (ビット分類、衝突マスクなどで使う)
gameObject.layer = LayerMask.NameToLayer("Enemy");
int mask = LayerMask.GetMask("Player", "Enemy");
Physics.Raycast(origin, dir, out hit, 100f, mask);

// LayerMask + Physics.IgnoreLayerCollision で当たり判定の有無を制御
Physics.IgnoreLayerCollision(8, 9, true);

GameObject の検索

// 名前で検索 (遅い、Start で一度だけ推奨)
GameObject p = GameObject.Find("Player");

// Tag で検索
GameObject p = GameObject.FindWithTag("Player");
GameObject[] enemies = GameObject.FindGameObjectsWithTag("Enemy");

// 型で検索 (Unity 2023+: FindFirstObjectByType / FindObjectsByType を推奨)
PlayerController pc = FindFirstObjectByType<PlayerController>();
PlayerController[] all = FindObjectsByType<PlayerController>(FindObjectsSortMode.None);

// ❌ 旧 API (Unity 2023 で非推奨)
FindObjectOfType<PlayerController>();
FindObjectsOfType<PlayerController>();

Prefab との関係

Prefab は GameObject のテンプレート。Project ウィンドウに保存され、シーン内に何度も Instantiate できます:

  • Hierarchy の GameObject を Project ウィンドウへドラッグ → Prefab 化
  • Prefab を編集すると、全インスタンスに変更が反映される
  • インスタンス側の変更は override として保持
  • Prefab Variant でテンプレートの派生を作成可能
  • Nested Prefab で Prefab の中に Prefab を入れられる

Singleton GameObject パターン

ゲーム全体で 1 つだけ存在するマネージャ用パターン:

public class GameManager : MonoBehaviour
{
    public static GameManager Instance { get; private set; }

    void Awake()
    {
        if (Instance != null && Instance != this)
        {
            Destroy(gameObject);
            return;
        }
        Instance = this;
        DontDestroyOnLoad(gameObject);
    }

    public int score;
    public void AddScore(int amount) { score += amount; }
}

// どこからでも
GameManager.Instance.AddScore(10);

ECS (Unity DOTS) との比較

Unity の伝統的 GameObject + MonoBehaviour は柔軟ですが、数千 〜 数万体を処理すると CPU/GC が辛くなります。Unity DOTS (Data-Oriented Technology Stack) の ECS はその解決策:

項目GameObject + ComponentECS (Entity Component System)
主体GameObject (オブジェクト指向)Entity (ID のみ、データなし)
データComponent 内に混在純粋データの Component (struct)
処理各 Component の UpdateSystem が一括処理
得意少数の凝った挙動大量同種オブジェクト
難易度低 (Unity 標準)高 (DOTS 学習必要)

FAQ

Q: Find() は遅いと聞くが?
A: シーン内の全 GameObject を線形探索するので遅い。Start() で 1 回だけ呼んでキャッシュするか、Inspector の public GameObject でドラッグ参照を推奨。

Q: GameObject を delete するのと SetActive(false) はどう違う?
A: Destroy はメモリ解放 + GC 対象、SetActive(false) は単に非表示 + 処理停止。再利用する弾丸・敵にはObject Pooling + SetActive がお得。

Q: GameObject の名前を実行時に変えていい?
A: 可能 (gameObject.name = "Foo") ですが、名前で Find している箇所が壊れます。識別は Tag / Layer / 参照キャッシュを推奨。