4.

Unity でオブジェクトの移動・回転を制御する完全ガイド

編集
この記事の要点
  • transform.position でワールド座標、transform.localPosition で親基準
  • 回転は transform.rotation (Quaternion)transform.eulerAngles
  • 相対移動は transform.Translate(Vector3 * speed * Time.deltaTime)
  • 物理挙動なら Rigidbody.AddForce / MovePosition を FixedUpdate で
  • スムーズな補間は Vector3.Lerp / Quaternion.Slerp

Transform の基本

すべての GameObject は Transform コンポーネントを持ち、位置 (Position) / 回転 (Rotation) / スケール (Scale) を表現します:

using UnityEngine;

public class Demo : MonoBehaviour
{
    void Start()
    {
        // ワールド座標
        Vector3 pos = transform.position;
        Quaternion rot = transform.rotation;
        Vector3 scale = transform.localScale;

        // 親基準のローカル座標
        Vector3 localPos = transform.localPosition;
        Quaternion localRot = transform.localRotation;

        Debug.Log($"World pos: {pos}, Local pos: {localPos}");
    }
}

位置の設定・取得

// 絶対位置で設定
transform.position = new Vector3(10, 0, 0);

// 1 軸だけ変えたいときは新しい Vector3 を代入
transform.position = new Vector3(transform.position.x, 5, transform.position.z);

// または分かりやすく
Vector3 p = transform.position;
p.y = 5;
transform.position = p;
// ※ transform.position.y = 5 は構造体のコピーへの代入なのでコンパイルエラー

// 親基準のローカル座標
transform.localPosition = Vector3.zero;   // 親の原点

相対移動: Translate

public float speed = 5f;

void Update()
{
    // 毎フレーム前方に移動(Time.deltaTime で frame rate 非依存)
    transform.Translate(Vector3.forward * speed * Time.deltaTime);

    // キー入力で操作
    float h = Input.GetAxis("Horizontal");
    float v = Input.GetAxis("Vertical");
    Vector3 move = new Vector3(h, 0, v) * speed * Time.deltaTime;
    transform.Translate(move);

    // ワールド座標で動かしたい場合(デフォルトはローカル空間)
    transform.Translate(Vector3.up * speed * Time.deltaTime, Space.World);
}

Time.deltaTime の重要性

フレームレートが 60 FPS なら毎フレーム 1/60 秒、30 FPS なら 1/30 秒。Time.deltaTime を掛けることで秒速 speed メートルになります:

// ❌ 悪い例: フレームレートに依存
transform.position += Vector3.forward * speed;
// 60 FPS では 60×speed 進む、30 FPS では 30×speed しか進まない

// ✅ 良い例: 秒速 speed
transform.position += Vector3.forward * speed * Time.deltaTime;

回転の設定: Quaternion vs Euler

Unity の内部表現は Quaternion(四元数)ですが、人間には Euler 角(XYZ 各軸の角度)が分かりやすいです:

// Euler 角で設定(度数法)
transform.eulerAngles = new Vector3(0, 90, 0);   // Y 軸 90 度

// Quaternion で設定
transform.rotation = Quaternion.Euler(0, 90, 0);
transform.rotation = Quaternion.AngleAxis(90, Vector3.up);   // Y 軸周り 90 度

// 別の方向に向ける
Vector3 target = new Vector3(10, 0, 10);
transform.rotation = Quaternion.LookRotation(target - transform.position);

// Quaternion の合成
Quaternion a = Quaternion.Euler(0, 30, 0);
Quaternion b = Quaternion.Euler(0, 60, 0);
transform.rotation = a * b;   // → Y 軸 90 度回転
EulerQuaternion
表現X/Y/Z の角度4 つの数値 (x, y, z, w)
分かりやすさ×
ジンバルロックありなし
補間不安定Slerp で滑らか
用途Inspector / 入力内部計算 / 補間

相対回転: Rotate

public float rotSpeed = 60f;   // 度/秒

void Update()
{
    // Y 軸周りに回転
    transform.Rotate(0, rotSpeed * Time.deltaTime, 0);

    // ワールド軸で回転
    transform.Rotate(Vector3.up, rotSpeed * Time.deltaTime, Space.World);

    // 指定軸(例: 対象を向く軸)
    transform.RotateAround(target.position, Vector3.up, rotSpeed * Time.deltaTime);
    // target を中心に公転(軌道運動)
}

Rigidbody による物理移動

物理演算 (重力 / 衝突) を使う場合、Transform を直接動かすと当たり判定がおかしくなります。Rigidbody を使い FixedUpdate で動かすのが正解:

public Rigidbody rb;
public float force = 10f;

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

void FixedUpdate()
{
    // 力を加える(慣性あり)
    rb.AddForce(Vector3.forward * force);

    // 速度を直接指定
    rb.velocity = new Vector3(0, 0, 5);

    // 位置を直接動かす(衝突は判定される)
    Vector3 newPos = rb.position + Vector3.forward * Time.fixedDeltaTime;
    rb.MovePosition(newPos);

    // 回転
    Quaternion deltaRot = Quaternion.Euler(0, rotSpeed * Time.fixedDeltaTime, 0);
    rb.MoveRotation(rb.rotation * deltaRot);
}
方法用途
AddForce外力を加える(自然な物理)
velocity = 速度を直接設定
MovePosition位置を補間移動(Kinematic でも有効)
transform.position = テレポート(衝突無視)

Lerp / Slerp(補間)

public Transform target;
public float smooth = 5f;

void Update()
{
    // 位置を滑らかに追従
    transform.position = Vector3.Lerp(
        transform.position,
        target.position,
        smooth * Time.deltaTime
    );

    // 回転を滑らかに追従(Slerp は球面線形補間)
    transform.rotation = Quaternion.Slerp(
        transform.rotation,
        target.rotation,
        smooth * Time.deltaTime
    );

    // 一定速度の Lerp は MoveTowards
    transform.position = Vector3.MoveTowards(
        transform.position,
        target.position,
        speed * Time.deltaTime
    );
}

方向ベクトル系プロパティ

// 自分の前方ベクトル(回転を反映)
Vector3 forward = transform.forward;    // ローカル Z 軸のワールド方向

Vector3 right = transform.right;        // ローカル X 軸
Vector3 up = transform.up;              // ローカル Y 軸

// 前方に進む
transform.position += forward * speed * Time.deltaTime;
// = transform.Translate(Vector3.forward * speed * Time.deltaTime);

FAQ

Q: transform.position.x = 5 がエラーになる
A: Vector3 は構造体(値型)。transform.position のコピーを変更しても本体に反映されない。新しい Vector3 を作って代入する。

Q: 物理オブジェクトが壁をすり抜ける
A: transform.position で動かしている可能性。Rigidbody.MovePositionFixedUpdate で使う。または Collision Detection を Continuous に。

Q: 高速回転でジンバルロックが起きる
A: Euler 角を使っているのが原因。Quaternion を直接扱うか、X 軸を ±90 度に近づけない設計に。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. スクリプトの作成と実行
  2. C# のクラス一覧
  3. シーンの移動方法
  4. オブジェクトの移動・回転
  5. キーボードの入力値を受け取る
  6. オブジェクトの取得とコンポーネントの取得
  7. 衝突時の処理
  8. Webページを開く
  9. コンポーネントの取得
  10. 処理を一定時間待つ
  11. コンソールへのログ出力方法
  12. 飛行機の加速と減速
  13. ジェットエンジンのエフェクトとオーディオ