最简单的一种就是先设置好摄像机跟物体的相对距离,
在脚本里就可以由物体的位置,跟相对距离,就可以求出摄像机的位置,
用插值的方法可以让摄像机平滑跟随。
1 public class CamFollow1 : MonoBehaviour 2 { 3 4 private Vector3 offset; 5 public Transform player; 6 7 void Start() 8 { 9 offset = player.position - transform.position; 10 } 11 12 void Update() 13 { 14 transform.position = Vector3.Lerp(transform.position, player.position - offset,Time.deltaTime*5); 15 } 16 }
实现一种注视的效果,可以对rotation做下处理
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); }
这样子,人物在走动的时候,摄像机就是一边注视着人物,一边跟着移动。
但是,当有墙体,或其他高大的物体遮挡住人物,
摄像机就无法看到人物,玩家自然也看不到,
在上面的基础上做更近一步的扩展
在人物头顶往下看,肯定可以看得到人物,
所以我们要做的就是把摄像机的位置向人物头顶去调整,直到可以看到人物。

1 using UnityEngine; 2 using System.Collections; 3 4 public class CamFollow3 : MonoBehaviour 5 { 6 7 8 private Transform player;//英雄位置 9 private Vector3 offset; //摄像机和英雄相对位置 10 private float distance;//距离 11 private Vector3[] points = new Vector3[5];//5个点作为摄像机位置的选择 12 13 private Vector3 targetPos;//筛选后的摄像机位置 14 15 void Awake() 16 { 17 player = GameObject.FindWithTag("Player").transform; 18 offset = transform.position - player.position; 19 distance = offset.magnitude; 20 } 21 22 void FixedUpdate() 23 { 24 //更新5个点的位置 25 points[0] = player.position + offset; 26 points[4] = player.position + Vector3.up*distance; 27 28 points[1] = Vector3.Lerp(points[0], points[4], 0.25f); 29 points[2] = Vector3.Lerp(points[0], points[4], 0.5f); 30 points[3] = Vector3.Lerp(points[0], points[4], 0.75f); 31 points[4] = Vector3.Lerp(points[0], points[4], 0.9f); 32 33 targetPos = FindCameraTarget(); 34 35 AdjustCamera(); 36 } 37 38 private Vector3 FindCameraTarget() 39 { 40 Vector3 result = points[points.Length - 1];//头顶位置 41 42 //从低到高遍历 43 for (int i = 0; i < points.Length; ++i) 44 { 45 if (IsHitPlayer(points[i], player.position)) 46 { 47 result = points[i]; 48 break; 49 } 50 } 51 52 return result; 53 } 54 55 private Ray ray; 56 private RaycastHit hit; 57 /// <summary> 58 /// 从origin发射一条射线检测是否碰到player, 59 /// 碰到则表示摄像机在此位置可以看到player 60 /// </summary> 61 /// <param name="origin"></param> 62 /// <param name="target"></param> 63 /// <returns></returns> 64 bool IsHitPlayer(Vector3 origin, Vector3 target) 65 { 66 bool result = false; 67 68 Vector3 dir = target - origin; 69 ray = new Ray(origin,dir); 70 if (Physics.Raycast(ray, out hit)) 71 { 72 if (hit.transform.tag == "Player") 73 { 74 result = true; 75 } 76 } 77 return result; 78 } 79 80 /// <summary> 81 /// 调整摄像机位置 82 /// </summary> 83 void AdjustCamera() 84 { 85 86 transform.position = Vector3.Slerp(transform.position, targetPos, Time.deltaTime * 6); 87 88 Quaternion rotation = Quaternion.LookRotation(player.position - transform.position); 89 transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * 33f); 90 91 } 92 }