java摄像头跟随,第三人称越肩视角摄像机跟随实现(防止进入墙壁)

目录结构:

67d4b58491510f7ac6bef92f334bb9e3.png

实现代码:

using UnityEngine;

public class CameraFollow : MonoBehaviour

{

[SerializeField]

private Transform m_tCamera; //相机transform

[SerializeField]

private Transform m_tCameraRoot; //相机旋转中心transform

[SerializeField]

private Transform m_tHead; //相机lookat的头部transform

private const float m_fDefaultDistance = 2.0f; //相机默认与中心点的距离

private const float m_fMinDistance = 1.995f; //相机与中心点的最小距离,在游戏中相机可能离中心点越来越近,设置一个最小值防止贴到人物头上去

void Start()

{

m_vCameraLastPosition = m_tCamera.localPosition;

}

// Update is called once per frame

void LateUpdate()

{

CameraUpdate();

}

private Ray m_CameraRay; //相机发出的射线

private RaycastHit m_CameraRaycastHit; //相机射线射到的点

private Vector3 m_vCameraLastPosition; //相机上次在的位置,如果相机入墙了就恢复到上次的位置

private Vector3 m_vCameraDir; //相机之于中心的单位方向

private void CameraUpdate()

{

m_tCamera.LookAt(m_tHead);

m_CameraRay = new Ray(m_tCamera.position, m_tCamera.forward * (m_fDefaultDistance + 0.5f));

if (Input.GetAxis("Mouse X") != 0) //鼠标移动相机围绕相机中心点旋转

{

m_tCamera.RotateAround(m_tCameraRoot.position, new Vector3(0, 1, 0), Input.GetAxis("Mouse X"));

}

if (Input.GetAxis("Mouse Y") != 0)

{

m_tCamera.RotateAround(m_tCameraRoot.position, new Vector3(1, 0, 0), -Input.GetAxis("Mouse Y"));

}

if(Physics.Raycast(m_CameraRay, out m_CameraRaycastHit, m_fDefaultDistance + 0.5f))

{

if(m_CameraRaycastHit.collider.CompareTag("Player")) //如果相机射线射到的点不是Player

{

m_vCameraLastPosition = m_tCamera.localPosition; //记录相机现在的位置为上一次的点

if (Vector3.Distance(m_tCameraRoot.position, m_tCamera.position) < m_fMinDistance) //如果相机和中心的距离小于最小距离了,lerp到安全距离

{

m_vCameraDir = m_tCamera.localPosition.normalized;

m_tCamera.localPosition = Vector3.Lerp(m_tCamera.localPosition, m_fDefaultDistance * m_vCameraDir, 0.3f);

}

}

else //如果相机射线射到的点不是Player,说明入墙了,lerp回上次记录的点

{

m_tCamera.localPosition = Vector3.Lerp(m_tCamera.localPosition, m_vCameraLastPosition, 0.3f);

}

}

}

}

游戏效果:

7cf696f787a135637da9f3b118cc43fa.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值