1. 程式人生 > >unity3相機跟隨物體移動

unity3相機跟隨物體移動

1.向量轉四元數
Quaternion.LookRotation(dir);—>返回值就是一個四元數
2.開始旋轉
transform.rotation = Quaternion.Lerp(當前的四元數, 目標四元數, 旋轉的速度);
3.普通相機跟隨
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraMovement : MonoBehaviour {
///
/// 跟隨目標
///
public Transform followTarget;
///
/// 方向向量
///
private Vector3 dir;

private void Start()
{
    //獲取方向向量
    dir = transform.position - followTarget.position;
}

private void Update()
{
    transform.position = dir + followTarget.position;
}

}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraMovement : MonoBehaviour {

/// <summary>
/// 俯視距離的偏移量
/// </summary>
public float offset = 0.5f;
/// <summary>
/// 設定中間的相機位置個數
/// </summary>
public int gears = 5;
/// <summary>
/// 跟隨目標
/// </summary>
public Transform followTarget;
/// <summary>
/// 方向向量
/// </summary>
private Vector3 dir;
/// <summary>
/// 待選的相機位置(觀察點)
/// </summary>
private Vector3[] readyPosition;
/// <summary>
/// 射線碰撞檢測器
/// </summary>
private RaycastHit hit;
/// <summary>
/// 相機跟隨的移動速度
/// </summary>
public int moveSpeed = 1;
/// <summary>
/// 相機旋轉的速度
/// </summary>
public float turnSpeed = 10f;
private void Start()
{
    //獲取方向向量
    dir = transform.position - followTarget.position;
    //例項化觀察點陣列
    readyPosition = new Vector3[gears];

}

private void Update()
{
    //相機的起點--->相機最佳視角
    Vector3 begin = dir + followTarget.position;
    //相機的終點--->相機最差視角保證能看到玩家
    Vector3 end = followTarget.position + Vector3.up * (dir.magnitude - offset);
    //把起點和終點放到觀察點的陣列中
    readyPosition[0] = begin;
    readyPosition[readyPosition.Length - 1] = end;
    //獲取相機中間點的位置
    for (int i = 1; i < readyPosition.Length - 1; i++)
    {
        //求中間點各個點的座標,比例為i / (gears - 1)
        readyPosition[i] = Vector3.Lerp(begin, end, i / (readyPosition.Length - 1));
    }
    //備選方案--->前面所有的觀察點都看不到玩家
    //都看不到就把相機放到最佳視角
    Vector3 watchPoint = begin;
    //遍歷觀察點陣列,挑選我們最佳觀察點
    for (int i = 0; i < readyPosition.Length; i++)
    {
        if (CheckWatchPoint(readyPosition[i]))
        {
            //設定觀察點
            watchPoint = readyPosition[i];
            //得到觀察點退出迴圈
            break;
        }
    }
    //相機平滑移動到最佳觀察點
    transform.position = Vector3.Lerp(transform.position, watchPoint, Time.deltaTime * moveSpeed);
    /*
      //旋轉的不是很平滑
      //相機旋轉到最佳角度看向玩家
      transform.LookAt(followTarget);
     */
    //獲取方向向量
    Vector3 lookDir = followTarget.position - watchPoint;
    //獲取四元數
    Quaternion lookQua = Quaternion.LookRotation(lookDir);
    //平滑轉向玩家
    transform.rotation = Quaternion.Lerp(transform.rotation, lookQua, Time.deltaTime * turnSpeed);
    //固定相機y軸z軸的旋轉
    transform.eulerAngles = new Vector3(transform.eulerAngles.x, 0, 0);

}
/// <summary>
/// 檢測觀察點是否可以看到目標
/// </summary>
/// <param name="point">待選的觀察點</param>
/// <returns><c>true</c>看得到<c>false</c>看不到</returns>
bool CheckWatchPoint(Vector3 point)
{
    if (Physics.Raycast(point,followTarget.position - point,out hit))
    {
        //如果射線檢測到的是玩家
        if (hit.collider.tag == "Player")
        {
            return true;
        }
    }

    return false;
}

}

相機跟隨一直觀察角色背部

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraFollow : MonoBehaviour {

public Transform target;
public float distanceUp = 5f;
public float distanceAway = 5f;
public float smooth = 2f;//位置平滑移動值
public float camDepthSmooth = 2f;
// Use this for initialization
void Start()
{

}

// Update is called once per frame
void Update()
{
    // 滑鼠軸控制相機的遠近
    if ((Input.mouseScrollDelta.y < 0 && Camera.main.fieldOfView >= 3) || Input.mouseScrollDelta.y > 0 && Camera.main.fieldOfView <= 80)
    {
        Camera.main.fieldOfView += Input.mouseScrollDelta.y * camDepthSmooth * Time.deltaTime;
    }

}

void LateUpdate()
{
    //相機的位置
    Vector3 disPos = target.position + Vector3.up * distanceUp - target.forward * distanceAway;
    transform.position = Vector3.Lerp(transform.position, disPos, Time.deltaTime * smooth);
    //相機的角度
    transform.LookAt(target.position);
}

}