カクつかない追従カメラ
カメラをガタつかずプレイヤーに追従させるには?
カメラは LateUpdate で動かし、Update では動かしません。LateUpdate は他が動き終わった後に走るため確定位置を読めます。Rigidbody なら Interpolate も有効化を——物理はフレームと別周期です。
フォローカメラは 4 行のコードと、それをどこに置くかという判断 1 つだけで決まります。Update に置くと、プレイヤーがまだ動き終わっていない位置を読んでしまい、すべてのフレームが 1 コ遅れる —— 目には映像の揺れとして映ります。
Unity はすべての Update を実行し終えてから、すべての LateUpdate を実行します。前半の側にカメラを置くと、プレイヤーが次のフレームでやっと到達する位置を読むことになります。
必ず LateUpdate
Unity はシーン内のすべての Update を実行してから、すべての LateUpdate を実行します。このフレームの結果として何がどこにあるかに反応しなければならない処理は、LateUpdate に置くものです。フォローカメラはその典型例です。
using UnityEngine;
public class FollowCamera : MonoBehaviour
{
public Transform target;
public Vector3 offset = new Vector3(0f, 6f, -8f);
[Range(1f, 30f)]
public float smooth = 10f;
void LateUpdate()
{
if (target == null) return;
Vector3 wanted = target.position + offset;
// Frame-rate independent smoothing. A plain Lerp with a constant t
// moves further per second at higher frame rates.
transform.position = Vector3.Lerp(
transform.position, wanted, 1f - Mathf.Exp(-smooth * Time.deltaTime));
transform.LookAt(target.position + Vector3.up * 1.5f);
}
}プレイヤーが Rigidbody を使う場合
ここでは LateUpdate だけでは足りません。物理は 1 秒に 50 回進みますが、画面は 60、90、120 回描画されるため、ほとんどのフレームでプレイヤーは前回の物理ステップから一歩も動いていないのにカメラだけが動きます。このずれがジャッターの正体です。
プレイヤーの Rigidbody で Interpolate を Interpolate に設定してください。Unity は物理ステップの間を補間して描くようになり、カメラもなめらかな動きを追えるようになります。
これはプレイヤーだけに設定し、シーン内のすべての Rigidbody に有効にしないでください —— 補間は 1 つごとにメモリを消費しますが、木箱をじっと見ている人などいません。
カメラに追われている Rigidbody を transform.position で動かすのは絶対にやめてください。補間が完全に無効になり、揺れが即座に戻ってきます。
それでもなめらかではない?
他にカメラの position へ書き込んでいるものがないかを確認してください。1 つの transform を 2 つの script が奪い合う様子は、揺れと見分けがつきません。
まず Game view の Stats パネルでフレームレートを確認しましょう。30 FPS に固定したときのカクつきは、カメラ側のバグではありません。
カメラがプレイヤーの子になっているなら、そのスクリプトは削除してください —— 子ならすでに追従しています。スクリプトと親子関係が互いに引っ張り合うようになります。
これを作るレッスン
追従カメラ
この記事はそれだけで完結するレシピです。コースでは同じものを、5 つのタブを貫くひとつのプロジェクトの一部として作ります — カメラと入力 のレッスン 01。