Unityスクリプトとは

Unityスクリプトは、ゲームの動作やロジックを制御するC#プログラムです。

スクリプトでできること

  • 🎮 キャラクターの移動制御
  • 💥 当たり判定の処理
  • 🎯 ゲームロジックの実装
  • 🎨 UIの制御
  • 🔊 音声の再生

スクリプトの作成

新規スクリプトの作成手順

1. Projectウィンドウで右クリック
2. Create > C# Script を選択
3. ファイル名を入力(例: PlayerController)
4. ダブルクリックで開く

基本的なスクリプト構造

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        Debug.Log("ゲーム開始!");
    }

    // Update is called once per frame
    void Update()
    {
        // 毎フレーム実行される
    }
}

重要な要素

  • MonoBehaviour: すべてのUnityスクリプトの基底クラス
  • Start(): ゲーム開始時に1回だけ実行
  • Update(): 毎フレーム実行(通常60回/秒)

主要なライフサイクルメソッド

実行順序

Awake()    // 最初に実行(初期化)
  ↓
Start()    // Awakeの後に実行
  ↓
Update()   // 毎フレーム実行
  ↓
LateUpdate() // Updateの後に実行
  ↓
OnDestroy() // オブジェクト削除時

各メソッドの使い分け

public class LifecycleExample : MonoBehaviour
{
    void Awake()
    {
        // コンポーネントの初期化
        // 他のオブジェクトに依存しない初期化
    }

    void Start()
    {
        // ゲーム開始時の初期化
        // 他のオブジェクトを参照する初期化
    }

    void Update()
    {
        // 入力処理、移動処理など
        // 毎フレーム実行
    }

    void FixedUpdate()
    {
        // 物理演算(Rigidbodyの操作)
        // 固定間隔で実行(デフォルト0.02秒)
    }

    void LateUpdate()
    {
        // カメラの追従など
        // Updateの後に実行
    }
}

変数とフィールド

public変数(Inspectorで編集可能)

public class PlayerStats : MonoBehaviour
{
    public int health = 100;
    public float speed = 5.0f;
    public string playerName = "Player";
    public GameObject weapon;
}

SerializeField(privateだがInspectorに表示)

public class Enemy : MonoBehaviour
{
    [SerializeField] private int health = 50;
    [SerializeField] private float moveSpeed = 3.0f;
    
    // 外部からアクセスできないが、Inspectorで設定可能
}

Range属性でスライダー表示

[Range(0, 100)]
public int health = 100;

[Range(0.1f, 10.0f)]
public float speed = 5.0f;

入力処理

キーボード入力

void Update()
{
    // キーが押されている間
    if (Input.GetKey(KeyCode.W))
    {
        transform.Translate(Vector3.forward * Time.deltaTime * speed);
    }

    // キーが押された瞬間
    if (Input.GetKeyDown(KeyCode.Space))
    {
        Jump();
    }

    // キーが離された瞬間
    if (Input.GetKeyUp(KeyCode.Space))
    {
        Debug.Log("ジャンプ終了");
    }
}

Input System(新)

// 軸入力(WASD、矢印キー)
float horizontal = Input.GetAxis("Horizontal"); // -1 to 1
float vertical = Input.GetAxis("Vertical");     // -1 to 1

transform.Translate(new Vector3(horizontal, 0, vertical) * speed * Time.deltaTime);

マウス入力

void Update()
{
    // 左クリック
    if (Input.GetMouseButtonDown(0))
    {
        Fire();
    }

    // マウス位置
    Vector3 mousePos = Input.mousePosition;
    
    // マウスホイール
    float scroll = Input.GetAxis("Mouse ScrollWheel");
}

移動と回転

Transform操作

public class Movement : MonoBehaviour
{
    public float speed = 5.0f;
    public float rotationSpeed = 100.0f;

    void Update()
    {
        // 前方に移動
        transform.Translate(Vector3.forward * speed * Time.deltaTime);

        // 上に移動(ワールド座標)
        transform.Translate(Vector3.up * speed * Time.deltaTime, Space.World);

        // Y軸回転
        transform.Rotate(0, rotationSpeed * Time.deltaTime, 0);

        // 位置を直接設定
        transform.position = new Vector3(0, 1, 0);

        // 回転を直接設定(オイラー角)
        transform.rotation = Quaternion.Euler(0, 90, 0);
    }
}

Rigidbodyでの移動

public class PhysicsMovement : MonoBehaviour
{
    private Rigidbody rb;
    public float speed = 5.0f;

    void Start()
    {
        rb = GetComponent();
    }

    void FixedUpdate()
    {
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");

        Vector3 movement = new Vector3(h, 0, v) * speed;
        
        // 速度を設定
        rb.velocity = movement;

        // 力を加える
        rb.AddForce(movement, ForceMode.Force);
    }
}

当たり判定

OnTriggerイベント(Trigger)

public class TriggerExample : MonoBehaviour
{
    void OnTriggerEnter(Collider other)
    {
        Debug.Log("Triggerに入った: " + other.gameObject.name);
        
        if (other.CompareTag("Player"))
        {
            Debug.Log("プレイヤーが入った!");
        }
    }

    void OnTriggerStay(Collider other)
    {
        // Trigger内にいる間、毎フレーム呼ばれる
    }

    void OnTriggerExit(Collider other)
    {
        Debug.Log("Triggerから出た");
    }
}

OnCollisionイベント(物理衝突)

public class CollisionExample : MonoBehaviour
{
    void OnCollisionEnter(Collision collision)
    {
        Debug.Log("衝突した: " + collision.gameObject.name);
        
        // 衝突の力
        float impactForce = collision.relativeVelocity.magnitude;
        Debug.Log("衝突力: " + impactForce);
    }

    void OnCollisionStay(Collision collision)
    {
        // 接触している間
    }

    void OnCollisionExit(Collision collision)
    {
        // 離れた時
    }
}

コンポーネントの取得

自分のコンポーネント

public class ComponentAccess : MonoBehaviour
{
    private Rigidbody rb;
    private Animator animator;

    void Start()
    {
        // GetComponentで取得
        rb = GetComponent();
        animator = GetComponent();

        // 複数のコンポーネント
        Component[] components = GetComponents();
    }
}

子オブジェクトのコンポーネント

// 子オブジェクトから検索
Transform child = transform.Find("ChildName");

// 子孫すべてから検索
Animator animator = GetComponentInChildren();

// すべての子オブジェクトから取得
Animator[] animators = GetComponentsInChildren();

他のGameObjectのコンポーネント

public class FindObject : MonoBehaviour
{
    void Start()
    {
        // タグで検索
        GameObject player = GameObject.FindWithTag("Player");
        
        // 名前で検索
        GameObject enemy = GameObject.Find("Enemy");
        
        // タイプで検索(重い)
        PlayerController pc = FindObjectOfType();
    }
}

オブジェクトの生成と破棄

Instantiate(生成)

public class Spawner : MonoBehaviour
{
    public GameObject bulletPrefab;
    public Transform spawnPoint;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            // 生成
            GameObject bullet = Instantiate(bulletPrefab);
            
            // 位置と回転を指定して生成
            Instantiate(bulletPrefab, spawnPoint.position, spawnPoint.rotation);
            
            // 親を指定
            GameObject obj = Instantiate(bulletPrefab, transform);
        }
    }
}

Destroy(破棄)

// 即座に破棄
Destroy(gameObject);

// 3秒後に破棄
Destroy(gameObject, 3.0f);

// コンポーネントのみ破棄
Destroy(GetComponent());

// 無効化(破棄しない)
gameObject.SetActive(false);

Coroutine(コルーチン)

基本的な使い方

public class CoroutineExample : MonoBehaviour
{
    void Start()
    {
        // Coroutine開始
        StartCoroutine(CountDown());
    }

    IEnumerator CountDown()
    {
        Debug.Log("3");
        yield return new WaitForSeconds(1.0f);
        
        Debug.Log("2");
        yield return new WaitForSeconds(1.0f);
        
        Debug.Log("1");
        yield return new WaitForSeconds(1.0f);
        
        Debug.Log("GO!");
    }
}

実用例

IEnumerator FadeOut()
{
    SpriteRenderer sprite = GetComponent();
    Color color = sprite.color;
    
    while (color.a > 0)
    {
        color.a -= Time.deltaTime;
        sprite.color = color;
        yield return null; // 次のフレームまで待機
    }
    
    Destroy(gameObject);
}

// Coroutineの停止
Coroutine fadeCoroutine = StartCoroutine(FadeOut());
StopCoroutine(fadeCoroutine);

実用的なスクリプト例

例1: シンプルなプレイヤー移動

public class SimplePlayer : MonoBehaviour
{
    public float speed = 5.0f;
    public float jumpForce = 5.0f;
    private Rigidbody rb;
    private bool isGrounded = true;

    void Start()
    {
        rb = GetComponent();
    }

    void Update()
    {
        // 移動
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");
        
        Vector3 movement = new Vector3(h, 0, v) * speed;
        rb.velocity = new Vector3(movement.x, rb.velocity.y, movement.z);

        // ジャンプ
        if (Input.GetKeyDown(KeyCode.Space) && isGrounded)
        {
            rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
            isGrounded = false;
        }
    }

    void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.CompareTag("Ground"))
        {
            isGrounded = true;
        }
    }
}

例2: カメラ追従

public class FollowCamera : MonoBehaviour
{
    public Transform target;
    public Vector3 offset = new Vector3(0, 5, -10);
    public float smoothSpeed = 0.125f;

    void LateUpdate()
    {
        Vector3 desiredPosition = target.position + offset;
        Vector3 smoothedPosition = Vector3.Lerp(transform.position, desiredPosition, smoothSpeed);
        transform.position = smoothedPosition;

        transform.LookAt(target);
    }
}

例3: アイテム収集

public class ItemCollector : MonoBehaviour
{
    private int score = 0;

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

まとめ

Unityスクリプトの基本をマスターすれば、ゲーム制作の幅が広がります

重要ポイント

  • MonoBehaviourの継承
  • Start()とUpdate()の使い分け
  • Time.deltaTimeで速度を調整
  • GetComponentでコンポーネント取得
  • Instantiate/Destroyでオブジェクト管理

次のステップ

  • Animatorでアニメーション制御
  • UIシステムの使い方
  • オーディオの再生
  • ScriptableObjectでデータ管理