Unity3d中第三人称摄像机跟随的实现

  最简单的一种就是先设置好摄像机跟物体的相对距离,
在脚本里就可以由物体的位置,跟相对距离,就可以求出摄像机的位置,
用插值的方法可以让摄像机平滑跟随。
 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 }

 

 
原文地址:https://www.cnblogs.com/dongz888/p/4909819.html