Unityにおける移動操作の方法とサンプルコード

本資料では、Unityでオブジェクトの移動(ポジション変更)を行うための様々なアプローチについて解説します。各手法の概要と具体的なサンプルコードを参考に、シーンの要件に合わせた最適な実装を検討してください。


1. Transformを利用した移動操作

1.1. Transform.Translate()

概要:
Transform.Translateは、現在の座標に対して指定したベクトル分だけオブジェクトを移動させます。ローカル座標系またはワールド座標系を指定可能です。

サンプルコード:

using UnityEngine;

public class TranslateExample : MonoBehaviour 
{
    void Update() 
    {
        // 毎フレーム、X方向に1単位/秒の速度で移動(ワールド座標)
        transform.Translate(Vector3.right * 1f * Time.deltaTime, Space.World);
    }
}

1.2. Transform.position の直接設定

概要:
Transform.positionプロパティに新しい座標を代入することで、オブジェクトの位置を直接変更します。補間やスムーズな動作は自前で実装する必要があります。

サンプルコード:

using UnityEngine;

public class DirectPositionExample : MonoBehaviour 
{
    void Update() 
    {
        // 目的の位置(例: X=0, Y=1, Z=0)に向けて毎フレーム線形補間
        transform.position = Vector3.Lerp(transform.position, new Vector3(0, 1, 0), Time.deltaTime);
    }
}

2. Rigidbodyを利用した移動操作

物理演算を利用する場合、Rigidbodyコンポーネントを通して自然な移動や衝突判定が行えます。

2.1. Rigidbody.AddForce()

概要:
AddForceは、Rigidbodyに対して力(Force)を加え、物理シミュレーション内で移動させます。重力や他の力との相互作用も考慮されます。

サンプルコード:

using UnityEngine;

public class AddForceExample : MonoBehaviour 
{
    public float forceAmount = 10f;
    private Rigidbody rb;

    void Start() 
    {
        rb = GetComponent<Rigidbody>();
    }

    void FixedUpdate() 
    {
        // 毎固定フレーム、前方(Z軸方向)に力を加える
        rb.AddForce(transform.forward * forceAmount);
    }
}

2.2. Rigidbody.MovePosition()

概要:
MovePositionは、Rigidbodyを指定した位置へスムーズに移動させます。キネマティックな動きとして扱われ、物理演算と衝突判定の整合性を保ちつつ位置を更新できます。

サンプルコード:

using UnityEngine;

public class MovePositionExample : MonoBehaviour 
{
    public float speed = 5f;
    private Rigidbody rb;

    void Start() 
    {
        rb = GetComponent<Rigidbody>();
    }

    void FixedUpdate() 
    {
        // 現在の位置から前方へ一定距離移動する新しい位置を計算
        Vector3 newPosition = rb.position + transform.forward * speed * Time.fixedDeltaTime;
        rb.MovePosition(newPosition);
    }
}

2.3. Rigidbody.velocity の直接設定

概要:
Rigidbody.velocityを直接設定することで、オブジェクトに即時の速度を与え、移動させる方法です。物理演算上、他の力や衝突などとの相互作用にも影響します。

サンプルコード:

using UnityEngine;

public class VelocityExample : MonoBehaviour 
{
    public float speed = 5f;
    private Rigidbody rb;

    void Start() 
    {
        rb = GetComponent<Rigidbody>();
    }

    void Update() 
    {
        // 入力に応じて移動方向を決定(例: 水平入力)
        float horizontal = Input.GetAxis("Horizontal");
        float vertical = Input.GetAxis("Vertical");
        Vector3 direction = new Vector3(horizontal, 0, vertical).normalized;
        rb.velocity = direction * speed;
    }
}

3. CharacterControllerを利用した移動操作

CharacterControllerは、主にプレイヤーキャラクターの移動に利用されるコンポーネントで、衝突判定や地形とのインタラクションが自動的に管理されます。

3.1. CharacterController.Move()

概要:
Moveメソッドは、CharacterControllerに対して相対的な移動ベクトルを与え、衝突判定や重力の影響を組み合わせた移動を実現します。

サンプルコード:

using UnityEngine;

public class CharacterControllerMoveExample : MonoBehaviour 
{
    public float speed = 5f;
    private CharacterController controller;
    private Vector3 moveDirection;

    void Start() 
    {
        controller = GetComponent<CharacterController>();
    }

    void Update() 
    {
        // 入力に応じた移動ベクトルを計算(例: WASD入力)
        float horizontal = Input.GetAxis("Horizontal");
        float vertical = Input.GetAxis("Vertical");
        moveDirection = new Vector3(horizontal, 0, vertical);
        moveDirection = transform.TransformDirection(moveDirection);
        moveDirection *= speed;

        // 重力を加味する場合(例: 簡易的な重力)
        moveDirection.y += Physics.gravity.y * Time.deltaTime;

        controller.Move(moveDirection * Time.deltaTime);
    }
}

3.2. CharacterController.SimpleMove()

概要:
SimpleMoveは、Moveよりもシンプルな移動を実現し、内部で重力が自動的に適用されます。ただし、明示的な垂直方向の移動制御はできません。

サンプルコード:

using UnityEngine;

public class SimpleMoveExample : MonoBehaviour 
{
    public float speed = 5f;
    private CharacterController controller;

    void Start() 
    {
        controller = GetComponent<CharacterController>();
    }

    void Update() 
    {
        // 入力に応じた水平移動を計算(例: WASD入力)
        float horizontal = Input.GetAxis("Horizontal");
        float vertical = Input.GetAxis("Vertical");
        Vector3 direction = new Vector3(horizontal, 0, vertical);
        direction = transform.TransformDirection(direction);
        controller.SimpleMove(direction * speed);
    }
}

4. NavMeshAgentを利用したナビゲーション移動

概要:
NavMeshAgentは、事前に作成したナビメッシュ上を自動的に移動するためのコンポーネントです。経路探索や障害物回避が可能なため、AIキャラクターの移動に適しています。

サンプルコード:

using UnityEngine;
using UnityEngine.AI;

public class NavMeshAgentExample : MonoBehaviour 
{
    public Transform target;
    private NavMeshAgent agent;

    void Start() 
    {
        agent = GetComponent<NavMeshAgent>();
    }

    void Update() 
    {
        // 常にターゲットの位置を目的地に設定
        agent.destination = target.position;
    }
}

まとめ

  • Transform操作
    • シンプルな移動の場合に有効。
    • Translateやpositionプロパティを利用し、手軽に移動制御が可能。ただし、物理演算や衝突処理は自前で対応する必要がある。
  • Rigidbodyを利用した移動
    • 物理演算を利用するため、自然な挙動や衝突判定が自動的に処理される。
    • AddForce、MovePosition、velocityの直接設定など、用途に応じた方法を選択する。
  • CharacterController
    • プレイヤーキャラクターなど、衝突判定を含む移動に最適。
    • MoveとSimpleMoveの使い分けで、重力や移動入力の処理が容易に行える。
  • NavMeshAgent
    • AIキャラクターの経路探索と移動に利用可能。
    • ナビメッシュを利用して自動的に障害物を回避しながら目的地に向かう。

各手法はシーンやゲームの要件に応じて選択してください。これらのサンプルコードを参考に、実際のプロジェクトで最適な移動操作を実装してみましょう。

Unity

Posted by hidepon