设玩家上方为最差观察点,相机原始位置为最佳观察点,当相机看不到玩家时,相机向前推进一档,直到看到玩家为止,挡位数量越多,位置越精细。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraFllow : MonoBehaviour {
/// <summary>
/// 摄像机挡位数量,越多精度越高
/// </summary>
public int gears = 5;
public float moveSpeed = 3f;
public float smooth = 3f;
private Transform fllowTarget;
private Vector3 dir;
private RaycastHit hit;
private void Awake()
{
fllowTarget = GameObject.FindWithTag(StealthConst.PLAYER).GetComponent<Transform>();
}
// Use this for initialization
void Start () {
dir = fllowTarget.position - transform.position;
}
// Update is called once per frame
void Update () {
//计算起点坐标(最佳观察点)
Vector3 start = fllowTarget.position - dir;
// 计算终点(最差观察点)
Vector3 end = fllowTarget.position + Vector3.up * (dir.magnitude-StealthConst.CAMERA_OFFSET);
//声明并实例化观察点数组
Vector3[] points = new Vector3[gears];
//将起始点放置到数组
points[0] = start;
points[points.Length - 1] = end;
//计算中间的点
for (int i = 0; i < points.Length - 1; i++)
{
points[i] = Vector3.Lerp(start, end, (float)i / (gears - 1));
}
//声明合适的坐标(初值相当于备胎)
Vector3 bestPos = start;
for (int i = 0; i < points.Length; i++)
{
if (CheckPoint(points[i]))
{
bestPos = points[i];
break;
}
}
//平滑移动到指定位置
transform.position = Vector3.Lerp(transform.position, bestPos, Time.deltaTime * moveSpeed);
//平滑看向玩家
Vector3 crDir = fllowTarget.position - bestPos;
//转成四元数
Quaternion quaternion = Quaternion.LookRotation(crDir);
transform.rotation = Quaternion.Lerp(transform.rotation, quaternion, Time.deltaTime * 3f);
transform.eulerAngles = new Vector3(transform.eulerAngles.x, 0, 0);
}
/// <summary>
/// 能否看到玩家
/// </summary>
/// <param name="point"></param>
/// <returns><c>true</c>可以看到 <c>false</c>不能s</returns>
bool CheckPoint(Vector3 point)
{
Vector3 currentDir = fllowTarget.position + Vector3.up * StealthConst.PLAYER_OFFSET - point;
if (Physics.Raycast(point, currentDir, out hit,Mathf.Infinity,1<<10))
{
if (hit.collider.CompareTag(StealthConst.PLAYER)) return true;
}
return false;
}
}
网友评论