功能实现:
1、跟随玩家,按住鼠标右键可自由移动相机视觉
2、相机不会到底地下
3、相机不会被遮挡
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class CameraFollow : MonoBehaviour
{
public const float DISTANCE_DEAFULT = 8.0f; //默认主角和摄像机的距离
private float curDistance = 0.0f; //运行时的距离
private Transform transTarget; //摄像机跟随目标(主角)
public float target_offsety = 0.5f; //盯着目标往上偏移值
private Vector3 vLooker; //摄像机盯着的位置
private Vector3 rotateXY; //保存X,Y方向的旋转,鼠标移动的时候会发生改变
private float speedAngelX = 200; //x方向的旋转速度
private float speedAngelY = 100; //y方向的旋转速度
public float minAngleAtY = -90.0f; //摄像机在Y方向的角度的最小值
public float maxAngleAtY = 90.0f; //摄像机在Y方向的角度的最大值
Quaternion rotation; //摄像机的旋转角度
void Start ()
{
curDistance = DISTANCE_DEAFULT;
transTarget = GameObject.FindGameObjectWithTag("Player").transform;
rotation = transform.rotation;
rotateXY.y = transform.eulerAngles.x;
rotateXY.x = transform.eulerAngles.y;
transform.position = transTarget.position + rotation * Vector3.back * curDistance;
}
void Update()
{
vLooker = transTarget.position;
vLooker.y += target_offsety;
if (Input.GetMouseButton(1))//0:左键,1:右键,2:中键
{
float x = Input.GetAxis("Mouse X");//鼠标在X方向上的移动,控制Y轴的旋转
float y = Input.GetAxis("Mouse Y");//鼠标在Y方向上的移动,控制X轴的旋转
rotateXY.x += speedAngelX * Time.deltaTime * x;
rotateXY.y -= speedAngelY * Time.deltaTime * y;
//在最小值和最大值之间取值
rotateXY.y = Mathf.Clamp(rotateXY.y, minAngleAtY, maxAngleAtY);
//相机旋转
rotation = Quaternion.Euler(rotateXY.y, rotateXY.x, 0);
transform.rotation = rotation;
}
transform.position = transTarget.position + rotation * Vector3.back * curDistance;
}
//一般用在摄像机的控制
//射线的碰撞检测
void LateUpdate()
{
if (transTarget)
{
//玩家的位置发送射线
RaycastHit[] hits = Physics.RaycastAll(new Ray(vLooker, (transform.position - vLooker).normalized));
curDistance = DISTANCE_DEAFULT;
List<RaycastHit> listHits = new List<RaycastHit>(hits);
foreach (RaycastHit hit in listHits)
{
if (hit.collider.gameObject.tag == "Player")
{
listHits.Remove(hit);
break;
}
}
if (listHits.Count > 0)
{
RaycastHit stand = listHits[0];
foreach (RaycastHit hit in listHits)
{
if (hit.distance < stand.distance)
{
stand = hit;
}
}
Debug.Log(stand.point + " " + stand.collider.gameObject.tag);
string tag = stand.collider.gameObject.tag;
curDistance = Vector3.Distance(stand.point, vLooker);
if (curDistance > DISTANCE_DEAFULT)
{
curDistance = DISTANCE_DEAFULT;
}
Vector3 position = transTarget.position + rotation * Vector3.back * curDistance;
//为了不让摄像机看到地下的东西
position.y += 1.5f;
transform.position = Vector3.Lerp(transform.position, position, 0.3f);
transform.LookAt(vLooker);
Debug.DrawRay(vLooker, position - vLooker, Color.red);
}
}
}
}