您的位置:首页 > 移动开发 > Unity3D

Unity3D 相机跟随算法

2017-08-01 10:19 274 查看
1.向量转四元数

Quaternion.LookRotation(dir);—>返回值就是一个四元数

2.开始旋转

transform.rotation = Quaternion.Lerp(当前的四元数, 目标四元数, 旋转的速度);

3.普通相机跟随

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

public class CameraMovement : MonoBehaviour {
/// <summary>
/// 跟随目标
/// </summary>
public Transform followTarget;
/// <summary>
/// 方向向量
/// </summary>
private Vector3 dir;

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

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

}


4.高级相机跟随,保证看到目标的相机最佳视角

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);
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息