unity摄像头跟随游戏主角移动

    xiaoxiao2021-03-25  122

    unity 中间摄像机的移动

    现在很多情况下都会出现游戏摄像机跟随着人物移动,网上关于这个也是很多的,但是有时候只是和游戏人物简单的出现保持相对的距离,这样子运动起来会很干涩,动作不够连贯,给游戏玩家很不好的感觉。

    如果遇到墙,和其他的物体对游戏主角进行遮挡,这个样子,就无法看到游戏玩家了。下面的方法巧妙的解决了这个问题。

    代码实现 

    首先定义几个变量: public float smooth = 1.5f; private Transform player; private Vector3 relCameraPos; //相对位置摄像机对人物 private float relCameraPosMag; //摄像机和人物的距离 private Vector3 newPos; //摄像机试着抵达的位置 对几个变量进行初始化: void Awake() { player = GameObject.FindGameObjectWithTag(Tags.player).transform; //摄像机相对位置 = 摄像机位置 - 玩家位置 relCameraPos = transform.position - player.position; //实际向量长度-0.5 小一点 relCameraPosMag = relCameraPos.magnitude - 0.5f; } 下面在fixedUpdate()里面是重点。 定义五个摄像机位置:Vector3[] checkPoints = new Vector3[5]; 再把第一个位置设为摄像机初始的位置,把最后一个位置设为于游戏人物垂直上方的位置。 //摄像机的初始位置 = 玩家位置 + 相对位置 Vector3 standardPos = player.position + relCameraPos; //摄像机的俯视位置 = 玩家位置 + 玩家正上方 * 相对位置向量长度 Vector3 abovePos = player.position + Vector3.up * relCameraPosMag; 摄像机如下图一步一步慢慢升上来的。 摄像头会慢慢位移,直到射线能过看到的地方。 checkPoints[4] = abovePos; for (int i = 0;i<checkPoints.Length;i++) { if (ViewingPosCheck(checkPoints[i])) { break; } } 其中,ViewPosCheck()函数是判断射线的 //使用光线投射的方法检测摄像机能否投射碰撞到玩家 bool ViewingPosCheck(Vector3 checkPos) { RaycastHit hit; if (Physics.Raycast(checkPos,player.position-checkPos,out hit,relCameraPosMag)) { if (hit.transform!=player) { return false; } } newPos = checkPos; return true; } 下面的函数使摄像机在运动的过程中始终面对着游戏人物。 //使摄像机函数在移动过程中始终面对玩家 void SmoothLookAt() { Vector3 relPlayPosition = player.position - transform.position; Quaternion lookAtRotation = Quaternion.LookRotation(relPlayPosition, Vector3.up); transform.rotation = Quaternion.Lerp(transform.rotation, lookAtRotation, smooth * Time.deltaTime); } 下面是代码的整个集合 using UnityEngine; using System.Collections; public class CameraMovement : MonoBehaviour { public float smooth = 1.5f; private Transform player; private Vector3 relCameraPos; //相对位置摄像机对人物 private float relCameraPosMag; //摄像机和人物的距离 private Vector3 newPos; //摄像机试着抵达的位置 void Awake() { player = GameObject.FindGameObjectWithTag(Tags.player).transform; //摄像机相对位置 = 摄像机位置 - 玩家位置 relCameraPos = transform.position - player.position; //实际向量长度-0.5 小一点 relCameraPosMag = relCameraPos.magnitude - 0.5f; } void FixedUpdate() { //摄像机的初始位置 = 玩家位置 + 相对位置 Vector3 standardPos = player.position + relCameraPos; //摄像机的俯视位置 = 玩家位置 + 玩家正上方 * 相对位置向量长度 Vector3 abovePos = player.position + Vector3.up * relCameraPosMag; Vector3[] checkPoints = new Vector3[5]; checkPoints[0] = standardPos; checkPoints[1] = Vector3.Lerp(standardPos, abovePos, 0.25f); checkPoints[2] = Vector3.Lerp(standardPos, abovePos, 0.5f); checkPoints[3] = Vector3.Lerp(standardPos, abovePos, 0.75f); checkPoints[4] = abovePos; for (int i = 0;i<checkPoints.Length;i++) { if (ViewingPosCheck(checkPoints[i])) { break; } } transform.position = Vector3.Lerp(transform.position, newPos, smooth * Time.deltaTime); SmoothLookAt(); } //使用光线投射的方法检测摄像机能否投射碰撞到玩家 bool ViewingPosCheck(Vector3 checkPos) { RaycastHit hit; if (Physics.Raycast(checkPos,player.position-checkPos,out hit,relCameraPosMag)) { if (hit.transform!=player) { return false; } } newPos = checkPos; return true; } //使摄像机函数在移动过程中始终面对玩家 void SmoothLookAt() { Vector3 relPlayPosition = player.position - transform.position; Quaternion lookAtRotation = Quaternion.LookRotation(relPlayPosition, Vector3.up); transform.rotation = Quaternion.Lerp(transform.rotation, lookAtRotation, smooth * Time.deltaTime); } }
    转载请注明原文地址: https://ju.6miu.com/read-14859.html

    最新回复(0)