一:相机跟随

——直接把相机作为要跟随物体的子物体
我在制作小地图相机的时候一般这样用其他的情况都不推荐


——计算偏移量求出相机正确的实时位置

using UnityEngine;

public class CameraController : MonoBehaviour
{
    public Transform targetPos;//跟随物体的位置
    private Vector3 offset;//偏移量

    private void Start()
    {
        offset = transform.position - targetPos.position;
    }

    private void LateUpdate()
    {
        transform.position = offset + targetPos.position;
    }
}


——算是方法2的升级版(插值移动)

using UnityEngine;

public class CameraController : MonoBehaviour
{
    public Transform targetPos;//跟随物体的位置
    private Vector3 offset;//偏移量

    public float smooth;//平滑度

    private void Start()
    {
        offset = transform.position - targetPos.position;
    }

    private void LateUpdate()
    {
        transform.position = Vector3.Lerp(transform.position, offset + targetPos.position, Time.deltaTime * smooth);
    }
}


——跟随的物体到达屏幕中心点再进行跟随
注意视口坐标转换时Z轴也需要转换,因为是对于相机的操作

using UnityEngine;

public class CameraController : MonoBehaviour
{
    public Transform targetPos;//跟随物体的位置

    private Vector3 velocity;//速度

    public float smooth;//平滑度

    private void LateUpdate()
    {
        Follow();
    }

    //相机跟随
    private void Follow()
    {
        Vector3 middlePos = Camera.main.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, -Camera.main.transform.position.z));
        Vector3 offset = targetPos.position - middlePos;
        Vector3 des = transform.position + offset;
        des.x = 0;
        if (des.y > transform.position.y)
        {
            transform.position = Vector3.SmoothDamp(transform.position, des, ref velocity, smooth);
        }
    }
}
using UnityEngine;

public class CameraController : MonoBehaviour
{
    public Transform targetPos;//跟随物体的位置

    private float velocity;//速度

    public float smooth;//平滑度

    private void LateUpdate()
    {
        Follow();
    }

    //跟随相机
    private void Follow()
    {
        float offsetY = targetPos.position.y - Camera.main.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, -Camera.main.transform.localPosition.z)).y;
        float targetY = offsetY + transform.localPosition.y;
        Vector3 pos = transform.localPosition;
        if (targetY > pos.y)
        {
            pos.y = Mathf.SmoothDamp(pos.y, targetY, ref velocity, smooth);
        }
        transform.localPosition = pos;
    }
}


——2D相机跟随中限制相机的范围,不超出边界(与Cineamachine中的2DCamera功能类似)

using UnityEngine;

public class CameraController : MonoBehaviour
{
    public Transform playerPos;//玩家位置

    private Vector3 offset;//偏移量

    private void Start()
    {
        offset = transform.position - playerPos.position;
    }

    private void LateUpdate()
    {
        Vector3 targetPos = playerPos.position + offset;
        transform.position = new Vector3(Mathf.Clamp(targetPos.x, -5.3f, 5.3f), Mathf.Clamp(targetPos.y, -3, 3), targetPos.z);
    }
}

二:相机的高级操作

using UnityEngine;

public class CameraController : MonoBehaviour
{
    private Transform playerPos;//玩家位置
    private Vector3 offset;//偏移量

    public int minZoom;//最小缩放
    public int maxZoom;//最大缩放
    public float followSpeed;//跟随的速度
    public float zoomSpeed;//缩放的速度
    public float rotateSpeed;//旋转的速度

    private bool isPress;//是否按下

    private void Start()
    {
        playerPos = GameObject.FindGameObjectWithTag(Tag.player).transform;
        offset = this.transform.position - playerPos.position;
    }

    private void LateUpdate()
    {
        Follow();
        Rote();
        Zoom();
    }

    //相机跟随
    private void Follow()
    {
        this.transform.position = Vector3.Lerp(this.transform.position, playerPos.position + offset, followSpeed * Time.deltaTime);
    }

    //相机缩放
    private void Zoom()
    {
        float distance = offset.magnitude;
        distance = Mathf.Clamp(distance += Input.GetAxis("Mouse ScrollWheel") * zoomSpeed, minZoom, maxZoom);
        offset = offset.normalized * distance;
    }

    //相机旋转
    private void Rote()
    {
        if (Input.GetMouseButtonDown(1))
        {
            isPress = true;
        }
        if (Input.GetMouseButtonUp(1))
        {
            isPress = false;
        }

        if (isPress)
        {
            Vector3 oriPos = transform.position;
            Quaternion oriRot = transform.rotation;

            transform.RotateAround(playerPos.position, playerPos.up, Input.GetAxis("Mouse X") * rotateSpeed);
            transform.RotateAround(playerPos.position, transform.right, -Input.GetAxis("Mouse Y") * rotateSpeed);

            float x = transform.eulerAngles.x;
            if (x < 10 || x > 70)
            {
                transform.position = oriPos;
                transform.rotation = oriRot;
            }
        }
        offset = this.transform.position - playerPos.position;
    }
}