相机组件结构:
一般是相机根节点处理,相机跟随,旋转。
mainCamera处理相机距离。
当角色靠近墙壁,墙壁处于摄像机和角色之间时,会遮挡角色,处理方法是,把相机距离拉近。
public class Test : MonoBehaviour {
protected bool isHadCol; //外部调用 是否相机被遮挡
public Transform m_camera; //相机
public Transform m_camera_parent; //相机父控件
public Transform m_target; //相机跟随目标
public float m_clipMoveTime = 0.2f; //剪裁速度
public float m_backMoveTime = 0.5f; //回归速度
public string[] m_raycastLayerName = { "CameraCollide" };
private int m_raycastLayer = 0;
private float m_raycastDistance = 33.0f; //射线长度
private float m_defaultDistance;
private float m_curDistance;
RaycastHit[] m_raycastHitsArray = new RaycastHit[8];
private List<float> m_dist = new List<float>();
private Ray m_ray = new Ray();
private float m_MoveVelocity;
void Start () {
if (!m_camera) {
m_camera = GetComponentInChildren<Camera>().transform;
}
m_camera_parent = m_camera.parent;
m_raycastLayer = 0;
for (int i = 0; i < m_raycastLayerName.Length; i++) {
m_raycastLayer |= 1 << LayerMask.NameToLayer(m_raycastLayerName[i]);
}
m_defaultDistance = m_camera.localPosition.magnitude;
m_curDistance = m_defaultDistance;
}
void LateUpdate () {
if (!m_target) return;
float m_targetDistance = m_defaultDistance;
m_ray.origin = m_target.position;
m_ray.direction = -m_camera.forward.normalized;
var hitCount = Physics.RaycastNonAlloc(m_ray, m_raycastHitsArray, m_raycastDistance, m_raycastLayer);
m_dist.Clear();
for (int i = 0; i < hitCount; i++) {
var hitGo = m_raycastHitsArray[i].collider.gameObject;
//todo 其他条件
m_dist.Add(m_camera_parent.InverseTransformPoint(m_raycastHitsArray[i].point).z);
}
if (m_dist.Count > 0)
{
m_dist.Reverse();
m_targetDistance = m_dist[0];
isHadCol = true;
}
else {
isHadCol = false;
}
Debug.DrawRay(m_ray.origin, m_ray.direction * m_raycastDistance, Color.red);
m_curDistance = Mathf.SmoothDamp(m_curDistance, m_targetDistance, ref m_MoveVelocity,
m_curDistance <= m_targetDistance ? m_clipMoveTime : m_backMoveTime);
m_curDistance = Mathf.Clamp(m_curDistance, 0, 10);
m_camera.localPosition = Vector3.forward * m_curDistance;
}
}