本日は Unity の小ネタ枠です。
指定のトランスフォームを中心にオブジェクトを回転させながら追従させる方法を記事にします。
今回は指定のオブジェクトに徐々に近づけることで科学館でよく見る万有引力の動きをそれっぽく再現してみます。
前提条件
前回記事の続きです。
bluebirdofoz.hatenablog.com
bluebirdofoz.hatenablog.com
Vector3.Lerp
直線上にある 2 つのベクトル間を補間します。
本記事では徐々にターゲットオブジェクト方向に近づけるために利用します。
docs.unity3d.com
public static Vector3 Lerp (Vector3 a, Vector3 b, float t);
引数 | 説明 |
---|---|
a | 開始位置 |
b | 到達位置 |
t | 移動割合(0.0~1.0) |
サンプルシーン
以下の通り、サンプルスクリプトを修正しました。
ターゲットオブジェクトの周囲を中心に回転しながら、徐々にターゲットオブジェクトに近づいていきます。
そして距離が近づくほど、回転の速度が上昇していきます。
・RotateAroundTargetGravitation.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; public class RotateAroundTargetGravitation : MonoBehaviour { [SerializeField, Tooltip("開始位置オブジェクト")] private GameObject StartObject; [SerializeField, Tooltip("ターゲットオブジェクト")] private GameObject TargetObject; [SerializeField, Tooltip("開始時の回転速度係数")] private float SpeedFactor = 0.1f; [SerializeField, Tooltip("Lerp係数")] private float LerpFactor = 0.01f; [Tooltip("開始時の2点間の距離")] private float RadiusDistance; [Tooltip("回転軸")] // 回転軸はY軸(縦軸)に固定する private Vector3 RotateAxis = Vector3.up; private void Start() { // 各オブジェクト位置を取得する Vector3 startPosition = StartObject.transform.position; Vector3 targetPosition = TargetObject.transform.position; // 初期位置はスタートオブジェクトと同じ位置に設定する this.transform.position = startPosition; // 開始時の距離を取得する RadiusDistance = Vector3.Distance(startPosition, targetPosition); } // Update is called once per frame void Update() { if (StartObject == null || TargetObject == null) return; // 各オブジェクト位置を取得する Vector3 targetPosition = TargetObject.transform.position; Vector3 selfPosition = this.transform.position; // 現在の距離を取得する float currentRadiusDistance = Vector3.Distance(selfPosition, targetPosition); if (currentRadiusDistance < 0.1f) { // 一定以上に距離が近づいたら計算を終了する this.transform.position = TargetObject.transform.position; this.transform.rotation = TargetObject.transform.rotation; return; } // 距離が近づくほど回転速度を早くする float currentSpeedFactor = SpeedFactor * (RadiusDistance / currentRadiusDistance); // Leap関数を使って徐々にターゲットに近づいていく this.transform.position = Vector3.Lerp(selfPosition, targetPosition, LerpFactor); // 指定オブジェクトを中心に回転する this.transform.RotateAround( targetPosition, RotateAxis, 360.0f / (1.0f / currentSpeedFactor) * Time.deltaTime ); } }
シーンに Sphere オブジェクトを作成し、本スクリプトを追加します。
追従させるターゲットとして Cube オブジェクトを配置し手指定します。
開始位置のターゲットには[MainCamera]を指定します。
動作確認
シーンを再生して動作を確認します。
Sphere オブジェクトがカメラ位置から cube オブジェクトに向かって回転しながら落下していきます。
距離が近づくほど回転速度が速くなり、ターゲットオブジェクトの位置に到達します。