Unity3d中第三人称摄像机跟随的实现
整理了一下网络上一些关于unity中视角跟随的一些方法
通过同步摄像机的位置使其跟随Player的position变化
void Rot_moves() { float y = Input.GetAxis("Mouse X"); float x = Input.GetAxis("Mouse Y"); camAms.x -= x; camAms.y += y; camTrans.eulerAngles = camAms; //float Camx = this.transform.position.x + 2.0f; camTrans.position = new Vector3(this.transform.position.x , camTrans.position.y, this.transform.position.z ); float camy = camAms.y; this.transform.eulerAngles = new Vector3(this.transform.eulerAngles.x, camy, this.transform.eulerAngles.z); Vector3 stratpro = transform.position; stratpro.y += camnHight; camTrans.position = stratpro; }
但这种方法非常诡异,视角移动的非常不自然,而且视角相对固定,无法避免障碍物阻挡视角。
(但万一用上了呢?)
由物体的位置,跟相对距离,就可以求出摄像机的位置,用插值的方法可以让摄像机平滑跟随。
public class CamFollow1 : MonoBehaviour { private Vector3 offset; public Transform player; void Start() { offset = player.position - transform.position; } void Update() { transform.position = Vector3.Lerp(transform.position, player.position - offset,Time.deltaTime*5); Quaternion rotation = Quaternion.LookRotation(player.position - transform.position); transform.rotation = Quaternion.Slerp(transform.rotation, rotation,Time.deltaTime*3f); } }
其中的rotation的设置可以造成一些注视的效果,
这个方法虽然还是无法避免障碍物阻挡视线,但视角的变化已经非常平滑,个人感觉对付部分情景已经可以了。
但是!在我这个诡异的项目是不能满足的!
在平滑跟随的基础上避免障碍物阻挡视角
摄像机就无法看到人物,玩家自然也看不到,
在上面的基础上做更近一步的扩展
在人物头顶往下看,肯定可以看得到人物,
所以我们要做的就是把摄像机的位置向人物头顶去调整,直到可以看到人物。
但是为什么我的写出来是痴汉视角。。。。
先放上教程源代码吧
我好对比着魔改……
using UnityEngine; using System.Collections; public class CamFollow3 : MonoBehaviour { private Transform player;//英雄位置 private Vector3 offset; //摄像机和英雄相对位置 private float distance;//距离 private Vector3[] points = new Vector3[5];//5个点作为摄像机位置的选择 private Vector3 targetPos;//筛选后的摄像机位置 void Awake() { player = GameObject.FindWithTag("Player").transform; offset = transform.position - player.position; distance = offset.magnitude; } void FixedUpdate() { //更新5个点的位置 points[0] = player.position + offset; points[4] = player.position + Vector3.up*distance; points[1] = Vector3.Lerp(points[0], points[4], 0.25f); points[2] = Vector3.Lerp(points[0], points[4], 0.5f); points[3] = Vector3.Lerp(points[0], points[4], 0.75f); points[4] = Vector3.Lerp(points[0], points[4], 0.9f); targetPos = FindCameraTarget(); AdjustCamera(); } private Vector3 FindCameraTarget() { Vector3 result = points[points.Length - 1];//头顶位置 //从低到高遍历 for (int i = 0; i < points.Length; ++i) { if (IsHitPlayer(points[i], player.position)) { result = points[i]; break; } } return result; } private Ray ray; private RaycastHit hit; /// <summary> /// 从origin发射一条射线检测是否碰到player, /// 碰到则表示摄像机在此位置可以看到player /// </summary> /// <param name="origin"></param> /// <param name="target"></param> /// <returns></returns> bool IsHitPlayer(Vector3 origin, Vector3 target) { bool result = false; Vector3 dir = target - origin; ray = new Ray(origin,dir); if (Physics.Raycast(ray, out hit)) { if (hit.transform.tag == "Player") { result = true; } } return result; } /// <summary> /// 调整摄像机位置 /// </summary> void AdjustCamera() { transform.position = Vector3.Slerp(transform.position, targetPos, Time.deltaTime * 6); Quaternion rotation = Quaternion.LookRotation(player.position - transform.position); transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * 33f); } }
2019-12-19 16:39:03
整理:菰冭