滑らかな追従
CoddyのUnityジャーニー「物理演算とゲームプレイ」セクションの一部。レッスン 47/71。
LateUpdate()でプレイヤーの位置にオフセットを加えた位置をコピーするカメラでは、プレイヤーが揺れるたびに視点も揺れます。Vector3.SmoothDamp(current, target, ref velocity, smoothTime)は、減衰するバネのようにtargetへ近づく位置を返します。速度を上げ、目標に近づくにつれて減速し、行き過ぎることなく到達します。このカメラは、プレイヤーの3単位上、6単位後方から、少し遅れて追従します。
public Transform player;
public Vector3 offset = new Vector3(0, 3, -6);
public float smoothTime = 0.3f;
Vector3 velocity;
void LateUpdate()
{
Vector3 target = player.position + offset;
transform.position = Vector3.SmoothDamp(transform.position, target, ref velocity, smoothTime);
}refを使うと、コピーではなく変数そのものがSmoothDampに渡されるため、メソッドがその値を変更できます。SmoothDampは、カメラの3軸すべての現在の速度をvelocityに保持し、次のフレームでもその値を必要とするため、フィールドとして宣言しています。これをLateUpdate()内で宣言すると、毎フレーム0から始まるため、カメラは1フレームあたり約0.5%しか進まず、ゆっくりとしか動きません。カメラのズームなど、単一の数値の場合は、Mathf.SmoothDampもfloat型の速度を使って同じように動作します。
smoothTimeはカメラがどれだけ遅れて追従するかを設定します。0.3の場合、突然のジャンプの約60%分を0.3秒で移動し、1秒後にはほぼ到達します。値を小さくすると、より密着して追従します。SmoothDampはTime.deltaTimeを自動的に読み取るため、呼び出し時に何かをこれに掛ける必要はありません。
チャレンジ
中級カメラが一定の高さからプレイヤーを滑らかに追従するようにします。
- フィールド
Vector3 velocity;を追加します。 LateUpdate()内でVector3 target = new Vector3(player.position.x, height, player.position.z - back);を作成し、ホップしても視点が動かないようにします。transform.position = Vector3.SmoothDamp(transform.position, target, ref velocity, smoothTime);を設定します。
「プレイ」を押して、走ったりホップしたりしてみましょう。カメラは少し遅れて追従し、上下には揺れません。その後、「確認」を押します。
自分で試してみよう
using UnityEngine;
public class TopDownCamera : MonoBehaviour
{
public Transform player;
public float height = 12f;
public float back = 5f;
public float smoothTime = 0.25f;
void LateUpdate()
{
// 固定の高さを保ちながら、player の真上の位置(x)から back 単位だけ後方の位置(z)へ滑らかに移動する。
}
}
物理演算とゲームプレイのすべてのレッスン
自分で練習してみよう: Unityプレイグラウンド