功能实现:
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); } } } }