対象物(ターゲット)の方向を向く(2D)

2023年3月30日

3DプログラムではLookAtで可能ですが、2Dの場合、思うような動作になりません。下記のようにすることでtargetの方向に向きを変えることができます。

使うメソッドは、次のものになります
aからbへの回転を作成します

Quaternion.FromToRotation(a, b)

具体的には、次のように使います
Y座標(Vector3.up)をターゲットの方向(toDirection)に向かせるものになります

Quaternion.FromToRotation(Vector3.up, toDirection)

Vector3.upは、new Vector3(0, 1 , 0)です
真上のY軸を回転させて、toDirection(ベクトル)の方向に向かせる処理になります。

using UnityEngine;
public class LookAt2D : MonoBehaviour
{
    [SerializeField]
    GameObject target;
    void Update()
    {
        // 対象物へのベクトルを算出
        Vector3 toDirection = target.transform.position - transform.position;
        // 対象物へ回転する
        transform.rotation = Quaternion.FromToRotation(Vector3.up, toDirection);
    }
}

実行結果

タイアモンドオブジェクトにアタッチされているLookAt2DスクリプトのTargetフィールドに正方形を代入(アウトレット接続)します。これが追跡対象となるターゲットになります

ゆっくり向きを変える

Mathf.LerpAngleとQuaternion.Eulerを使用する方法

Mathf.LerpAngleは、二つの角度の間を補間することができる関数で、Quaternion.Eulerは、Euler角をQuaternionに変換する関数です。具体的には、現在の角度とターゲットの角度を計算して、LerpAngleで補間することで、ゆっくりとターゲットの方向を向くことができます。

public Transform target;
public float rotationSpeed = 2f;
 
void Update()
{
    Vector2 direction = target.position - transform.position;
    float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
    Quaternion targetRotation = Quaternion.Euler(0, 0, angle);
    transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);
}

Vector2.AngleとMathf.MoveTowardsAngleを使用する方法

Vector2.Angleは、二つのベクトルの角度を計算する関数で、Mathf.MoveTowardsAngleは、現在の角度から目標の角度に向かってゆっくりと角度を変化させる関数です。具体的には、現在の角度とターゲットの角度を計算して、MoveTowardsAngleで補間することで、ゆっくりとターゲットの方向を向くことができます。

public Transform target;
public float rotationSpeed = 2f;
 
void Update()
{
    Vector2 direction = target.position - transform.position;
    float angle = Vector2.Angle(Vector2.right, direction);
    float targetAngle = direction.y < 0 ? -angle : angle;
    float currentAngle = transform.eulerAngles.z;
    float newAngle = Mathf.MoveTowardsAngle(currentAngle, targetAngle, rotationSpeed * Time.deltaTime);
    transform.rotation = Quaternion.Euler(0, 0, newAngle);
}

どちらの方法でも、2Dの場合でもターゲットの方向を向くことができます。ただし、Mathf.LerpAngleを使用する方法では、ターゲットとの距離によっては正しい角度が得られない場合がありますので、その点に注意して使用してください。また、Mathf.MoveTowardsAngleを使用する方法では、角度の変化量を調整することで、滑らかな動きを実現できます。

Unity,小技

Posted by hidepon