6.

Unity C# スクリプト完全入門 — MonoBehaviour・ライフサイクル・Inspector 連携

編集
この記事の要点
  • Unity のスクリプトは C# + MonoBehaviour が基本。1 ファイル = 1 クラス推奨
  • 主要ライフサイクル: Awake → OnEnable → Start → Update → FixedUpdate → LateUpdate → OnDestroy
  • [SerializeField] で private フィールドも Inspector に出せる (推奨形)
  • GetComponent() で同オブジェクトの Component を取得 (Start で取りキャッシュ)
  • 物理判定は OnCollisionEnter / OnTriggerEnter、時間処理は Coroutine

スクリプトの基本構造

Unity の C# スクリプトは Project ウィンドウで右クリック → Create → C# Script で生成します。デフォルトで MonoBehaviour を継承したクラスが入っています。

using UnityEngine;

public class PlayerController : MonoBehaviour {
    // Inspector に公開 (推奨)
    [SerializeField] private float speed = 5f;
    [SerializeField] private GameObject bulletPrefab;

    // 内部のみ
    private Rigidbody rb;

    void Awake() {
        // 自身の Component 取得は Awake / Start で
        rb = GetComponent();
    }

    void Start() {
        Debug.Log("ゲーム開始");
    }

    void Update() {
        // 入力など毎フレーム
        float h = Input.GetAxis("Horizontal");
        transform.Translate(Vector3.right * h * speed * Time.deltaTime);
    }
}

MonoBehaviour のライフサイクル

メソッドタイミング用途
Awake()インスタンス生成直後 (1 回)自分の Component 取得、初期化
OnEnable()有効化されるたびイベント購読
Start()最初の Update 直前 (1 回)他オブジェクト参照取得
Update()毎フレーム入力 / 移動 / 通常ロジック
FixedUpdate()固定間隔 (デフォ 0.02 秒)物理演算 / Rigidbody 操作
LateUpdate()全 Update 完了後カメラ追従
OnDisable()無効化時イベント解除
OnDestroy()破棄時リソース解放

[SerializeField] による Inspector 公開

public class Demo : MonoBehaviour {
    // public は外部から書き換え可能 (推奨されない)
    public int oldStyle;

    // private + [SerializeField] が現代の推奨
    [SerializeField] private int hp = 100;
    [SerializeField] private string playerName = "勇者";
    [SerializeField] private Transform target;       // 参照型も OK
    [SerializeField] private GameObject[] enemies;   // 配列も OK

    // 範囲指定 (スライダー表示)
    [Range(0f, 100f)]
    [SerializeField] private float volume = 50f;

    // ヘッダで区切る
    [Header("移動設定")]
    [SerializeField] private float moveSpeed;
}

GetComponent でアクセス

// 同じ GameObject の Component
Rigidbody rb = GetComponent();
Animator anim = GetComponent();

// 親 / 子から取得
Animator parentAnim = GetComponentInParent();
Renderer[] childRends = GetComponentsInChildren();

// 他オブジェクトの Component
Transform target = GameObject.Find("Enemy").GetComponent();

// null チェックの定石
if (TryGetComponent(out var rb2)) {
    rb2.AddForce(Vector3.up);
}

衝突判定 (Collision / Trigger)

// Collider.isTrigger = false の場合
void OnCollisionEnter(Collision col) {
    if (col.gameObject.CompareTag("Enemy")) {
        Debug.Log("敵と衝突: " + col.contacts[0].point);
    }
}
void OnCollisionStay(Collision col) { /* 接触中 */ }
void OnCollisionExit(Collision col) { /* 離れた */ }

// isTrigger = true (すり抜け検知)
void OnTriggerEnter(Collider other) {
    if (other.CompareTag("Coin")) {
        Destroy(other.gameObject);
    }
}

コルーチン (時間処理)

using System.Collections;

public class CoroutineDemo : MonoBehaviour {
    void Start() {
        StartCoroutine(Sequence());
    }

    IEnumerator Sequence() {
        Debug.Log("1 秒待つ");
        yield return new WaitForSeconds(1f);

        Debug.Log("次のフレーム");
        yield return null;

        Debug.Log("FixedUpdate のタイミング");
        yield return new WaitForFixedUpdate();

        Debug.Log("条件待ち");
        yield return new WaitUntil(() => Input.GetKey(KeyCode.Space));

        Debug.Log("完了");
    }
}

Debug.Log で挙動確認

Debug.Log("普通のログ");
Debug.LogWarning("警告");
Debug.LogError("エラー");

// 値の出力
Debug.Log($"HP = {hp}, position = {transform.position}");

// 条件付き
Debug.Assert(hp > 0, "HP がマイナス");

// シーンビューに線を引く
Debug.DrawRay(transform.position, Vector3.forward * 5f, Color.red, 1f);

ScriptableObject (データ専用クラス)

シーンに属さない 共有データ を保存するアセット型です。武器の能力値や敵パラメータをテーブルで管理するのに最適。

using UnityEngine;

[CreateAssetMenu(fileName = "WeaponData", menuName = "Game/Weapon")]
public class WeaponData : ScriptableObject {
    public string weaponName;
    public int attack;
    public float range;
    public Sprite icon;
}

// 使う側
public class Player : MonoBehaviour {
    [SerializeField] private WeaponData currentWeapon;

    void Attack() {
        Debug.Log(currentWeapon.weaponName + " で " + currentWeapon.attack + " ダメージ");
    }
}

推奨 IDE と設定

IDE無料特徴
Visual Studio○ (Community)Unity 公式推奨。デバッガ強い
JetBrains Rider個人非商用は無料Unity 専用解析が最強
VS Code + C# Dev Kit軽量。OmniSharp 設定が必要

パフォーマンス Tips

  • Update での GetComponent / Find を禁止。Awake / Start でキャッシュ
  • 毎フレーム文字列連結しない (GC アロケーション)
  • Vector3.Distance より sqrMagnitude 比較が速い
  • 大量オブジェクトは Object Pool パターン
  • 計算量の多い処理は Coroutine や Job System で分散

FAQ

Q: Update と FixedUpdate の使い分けは?
A: 入力や見た目は Update、Rigidbody 操作 (AddForce / velocity) は FixedUpdate。

Q: public と [SerializeField] private はどちらが良い?
A: 後者。public はカプセル化を壊し、他クラスから書き換えられるリスクがあります。

Q: スクリプトをアタッチしたら CompilerError が出る
A: クラス名とファイル名が完全一致しているか確認。PlayerController.csclass PlayerController

編集
Post Share
子ページ
  1. スクリプトの作成と実行
  2. C# のクラス一覧
  3. シーンの移動方法
  4. オブジェクトの移動・回転
  5. キーボードの入力値を受け取る
  6. オブジェクトの取得とコンポーネントの取得
  7. 衝突時の処理
  8. Webページを開く
  9. コンポーネントの取得
  10. 処理を一定時間待つ
  11. コンソールへのログ出力方法
  12. 飛行機の加速と減速
  13. ジェットエンジンのエフェクトとオーディオ
同階層のページ
  1. Unityの導入方法
  2. エディタ(画面)の説明
  3. プロジェクトの作成と削除
  4. オブジェクト
  5. コンポーネント
  6. スクリプト
  7. アセットのインポート方法
  8. ゲームの実行/一時停止/コマ送り
  9. パッケージのインポート
  10. ゲームの公開(Build)方法
  11. 重力の変更
  12. 用語集
  13. エラー一覧
  14. おすすめアセット一覧