# Unity3D中第三人称视角的镜头跟随和目标锁定

## 实现过程

• 在初始化时设定摄像机和人物之间的相对位置和相对旋转角；
• 在需要锁定时找到人物最近的单位，使人物转向该单位，并将摄像机的水平面的旋转角设置至和人物相同；
• 如果一定范围内没有单位，则人物不需转向，摄像机仍然执行；

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

public class CameraController : MonoBehaviour
{
public GameObject player;
Vector3 distanceToPlayer;
Vector3 positionTarget,angleTarget;
float temp;

// Start is called before the first frame update
void Start()
{
distanceToPlayer = this.transform.position - player.transform.position;
angleTarget = this.transform.eulerAngles;
}

// Update is called once per frame
void Update()
{
CameraFollow();
if (Input.GetKey(KeyCode.Space))
{
CameraAngle();
}
this.transform.eulerAngles = Vector3.Lerp(this.transform.eulerAngles, angleTarget, 0.3f);
this.transform.position = Vector3.Lerp(this.transform.position, positionTarget, 0.3f);
}

void CameraFollow()
{
positionTarget = player.transform.position + Quaternion.AngleAxis(player.transform.rotation.eulerAngles.y, new Vector3(0, 1, 0)) * (distanceToPlayer);
}

void CameraAngle()
{
//找到最近的单位
Collider[] collidersAround = Physics.OverlapSphere(player.transform.position, 400);//Overlap一系的函数在检测总数不是太大的时候会优先获取更近的碰撞器
if (collidersAround.Length == 0)
{
//搜索不到目标就指向正前方
angleTarget = new Vector3(this.transform.eulerAngles.x, player.transform.eulerAngles.y, this.transform.eulerAngles.z);
return;
}
int closestEnemy = 0;
float closestDistance = 401;
for (int i = 0; i < collidersAround.Length; i++)
{
temp = (this.transform.position - collidersAround[i].gameObject.transform.position).sqrMagnitude;
closestEnemy = temp < closestDistance ? i : closestEnemy;
closestDistance = temp < closestDistance ? temp : closestDistance;
}
player.transform.LookAt(collidersAround[closestEnemy].gameObject.transform.position);
positionTarget = player.transform.position + Quaternion.AngleAxis(player.transform.rotation.eulerAngles.y, new Vector3(0, 1, 0)) * (distanceToPlayer);
angleTarget = new Vector3(this.transform.eulerAngles.x, player.transform.eulerAngles.y, this.transform.eulerAngles.z);
}

}



    void CameraAngle()
{
Collider[] collidersAround = Physics.OverlapSphere(player.transform.position, 400);
if (collidersAround.Length == 0)
{
angleTarget = new Vector3(this.transform.eulerAngles.x, player.transform.eulerAngles.y, this.transform.eulerAngles.z);
return;
}
int closestEnemy = 0;
float closestDistance = 401;
for (int i = 0; i < collidersAround.Length; i++)
{
temp = (this.transform.position - collidersAround[i].gameObject.transform.position).sqrMagnitude;
closestEnemy = temp < closestDistance ? i : closestEnemy;
closestDistance = temp < closestDistance ? temp : closestDistance;
}
player.transform.LookAt(collidersAround[closestEnemy].gameObject.transform.position);
positionTarget = player.transform.position + Quaternion.AngleAxis(player.transform.rotation.eulerAngles.y, new Vector3(0, 1, 0)) * (distanceToPlayer);
angleTarget = new Vector3(this.transform.eulerAngles.x, player.transform.eulerAngles.y, this.transform.eulerAngles.z);
//当越过0发生突变时（不是最短变化路径）加以矫正
if (Mathf.Abs(player.transform.eulerAngles.y - this.transform.eulerAngles.y) > 180)
{
angleTarget = new Vector3(this.transform.eulerAngles.x, player.transform.eulerAngles.y + (player.transform.eulerAngles.y > this.transform.eulerAngles.y ? -360 : 360), this.transform.eulerAngles.z);
}
}


• 点赞 1
• 评论 1
• 分享
x

海报分享

扫一扫，分享海报

• 收藏 2
• 手机看

分享到微信朋友圈

x

扫一扫，手机阅读

• 打赏

打赏

RefmBiox

你的鼓励将是我创作的最大动力

C币 余额
2C币 4C币 6C币 10C币 20C币 50C币
• 一键三连

点赞Mark关注该博主, 随时了解TA的最新博文

08-01
04-18
08-11 6877
09-15
01-20
03-02