##0.0 はじめに
プレイヤーなどにカメラを追従させる方法です。
色々な方法があると思いますが、今回はスクリプトから追従させる簡単な方法を紹介します。
##1.0 普通に追従
カメラ(Main Camera)に下記スクリプトを添付する。2Dゲーム上でプレイヤーをカメラが追っかける例です。カメラのz座標は-10fとしています。
Camera1.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Camera1 : MonoBehaviour {
[SerializeField] Transform playerTr; // プレイヤーのTransformをInspectorから入れる
private void Update() {
// カメラをプレイヤーの場所へ
transform.position = new Vector3(playerTr.position.x, playerTr.position.y, -10f);
}
}
##2.0 カメラの追従を制限する
カメラ移動の限界を設けることにより見せたくないエリアまでカメラを移動しない方法です。
下記スクリプトではMathf.Clampを使用して右上限界点(5,5)、左下限界点(-5,-5)を越えないようにしています。
Camera2.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Camera2 : MonoBehaviour {
[SerializeField] Transform playerTr; // プレイヤーのTransform
[SerializeField] Vector2 camaraMaxPos = new Vector2(5, 5); // カメラの右上限界点
[SerializeField] Vector2 camaraMinPos = new Vector2(-5, -5); // カメラの左下限界点
private void Update() {
transform.position = new Vector3(
Mathf.Clamp(playerTr.position.x, camaraMinPos.x, camaraMaxPos.x), // カメラの左右を制限
Mathf.Clamp(playerTr.position.y, camaraMinPos.y, camaraMaxPos.y), // カメラの上下を制限
-10f); // カメラz座標は-10f
}
}
##3.0 ゆっくり追従
Mathf.Lerpを使うと少し遅れてカメラが追従します。画面の移動が滑らかな動きになります。
Camera3.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Camera3 : MonoBehaviour {
[SerializeField] Transform playerTr; // プレイヤーのTransform
private void Update() {
transform.position = Vector3.Lerp(
transform.position,
playerTr.position + new Vector3(0, 0, -10), // カメラzの位置
2.0f * Time.deltaTime);
}
}
##4.0 まとめ
まとめると下記のような感じになります。
Update()はどの順番で呼ばれるかがランダムなため、処理の呼ばれるタイミングがばらばらでカメラの動きががカクつくときがあります。フレームの最後に呼ばれることが決まっているLateUpdate()を使うことで問題が改善されます。
Camera4.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Camera4 : MonoBehaviour {
[SerializeField] Transform playerTr; // プレイヤーのTransform
[SerializeField] Vector3 cameraOrgPos = new Vector3(0, 0 ,-10f); // カメラの初期位置位置
[SerializeField] Vector2 camaraMaxPos = new Vector2(5, 5); // カメラの右上限界座標
[SerializeField] Vector2 camaraMinPos = new Vector2(-5, -5); // カメラの左下限界座標
void LateUpdate() {
Vector3 playerPos = playerTr.position; // プレイヤーの位置
Vector3 camPos = transform.position; // カメラの位置
// 滑らかにプレイヤーの場所に追従
camPos = Vector3.Lerp(transform.position, playerPos + cameraOrgPos, 3.0f * Time.deltaTime);
// カメラの位置を制限
camPos.x = Mathf.Clamp(camPos.x, camaraMinPos.x, camaraMaxPos.x);
camPos.y = Mathf.Clamp(camPos.y, camaraMinPos.y, camaraMaxPos.y);
camPos.z = -10f;
transform.position = camPos;
}
}