滑らかな追従
CoddyのUnityジャーニー「物理演算とゲームプレイ」セクションの一部。レッスン 45/63。
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.SmoothDampとsmoothTime(0.25)を使って滑らかに追従させ、次の位置へ徐々に近づけます。
- x:プレイヤーのx座標。
- z:プレイヤーの後方、-z方向に
back(5)単位。 - y:プレイヤー自身の高さにかかわらず、常に
height(12)。Spaceキーでプレイヤーがジャンプしても、視点は上下に揺れてはいけません。
Playを押して、走ったりジャンプしたりしてから、Checkを押します。
自分で試してみよう
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)の位置へ滑らかに移動する。
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。