利用射线 Camera智能追随目标

		using UnityEngine;
		using System.Collections;
		using System.IO;
		using System.Reflection;
	
		//挂载在Camere上
		public class ExerciseScript : MonoBehaviour
		{
	
	
	
			public float m_TurnSpeed = 10f;
			//被追随的主角的Transform
			private Transform m_Player;
			//最合适的观察点
			Vector3 fitPoint;
			//主角与摄像机的向量差
			Vector3 dir;
			//主角到摄像机合适的距离
			float m_Distance;
			//通用移动速度
			float m_MoveSpeed;
	
	
	
			void Awake ()
			{
				m_Player = GameObject.FindWithTag ("Player").transform;
				//第一次进来就拿到摄相机与主角的方向向量
				dir = m_Player.position - transform.position;
				//摄像机与主角的距离
				m_Distance = dir.magnitude - 0.5f;
				//magnitude 是取模(绝对值,只要大小)
			}
	
	
			// Use this for initialization
			void Start ()
			{
	
	
	
	
	
	
			}
	
			// Update is called once per frame
			void Update ()
			{
	
				CameraFollow ();
			}
			void CameraFollow (){
				//第一个观察点[修复BUG:摄像机延迟跟随]
				Vector3 beginPoint = m_Player.position - dir;
				//最后一个观察点
				Vector3 endPoint = m_Player.position + Vector3.up * m_Distance;
				//观察点数组
				Vector3[] watchPoints = new Vector3[5];
				//将第一个观察点设置到数组中
				watchPoints [0] = beginPoint;
				//将第五个观察点设置到数组中
				watchPoints [4] = endPoint;
				//获取其中三个观察点
				watchPoints [1] = Vector3.Lerp (beginPoint, endPoint, 0.25f);
				watchPoints [2] = Vector3.Lerp (beginPoint, endPoint, 0.5f);
				watchPoints [3] = Vector3.Lerp (beginPoint, endPoint, 0.75f);
				//最终合适的观察点(先给一个初始位置)
				fitPoint = transform.position;
				//遍历观察点,找到合适的点(射线可以直接射到物体)
				foreach (Vector3 item in watchPoints) {
					if (CanWatchPlayer (item)){
						//确定合适的观察点
						fitPoint = item;
						break;
						//找到合适点后调出循环,节省资源.
					}
				}
				print (fitPoint);
				//将摄像机移动到合适的位置
				transform.position = Vector3.Lerp (transform.position, fitPoint, Time.deltaTime * m_MoveSpeed);
				//让摄像机平滑的看着主角
				SmoothLookAt ();
			}
			void SmoothLookAt (){
				//主角与摄像机之间的方向向量
				Vector3 dir = m_Player.position - transform.position;
				//转成四元数
				Quaternion qua = Quaternion.LookRotation (dir);
				//将摄像机平滑旋转到目标方向
				transform.rotation = Quaternion.Lerp (transform.rotation, qua, Time.deltaTime * m_TurnSpeed);
				transform.eulerAngles = new Vector3 (transform.eulerAngles.x, 0, 0);
			}
			bool CanWatchPlayer (Vector3 currentPoint){
				//射线碰撞检测器
				RaycastHit hit;
				//当前方向向量
				Vector3 currentDir = m_Player.position - currentPoint;
				//发射物理射线
				if (Physics.Raycast (currentPoint, currentDir, out hit)) {
					//如果射线碰撞的是主角
					if (hit.collider.tag == "Player") {
						return true;
					}
				}
				//其他情况一律返回
				falsereturn false;
			}
		}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值