using UnityEngine;
using System.Collections;

public class CameraController : MonoBehaviour {

public Transform target ; //目标物体
public LayerMask mask;//layer层           //只检测在mask 包含的层里的碰撞体是否会遮挡视线
 
public float targetHeight = 2.0f; //实际聚焦点位置处于目标坐标上方的高度值          //不宜过高,否则会影响视线检测的位置
public float distance = 5.0f;// 摄像机距离实际聚焦点的距离
 
public float maxDistance = 20; //摄像机距离实际聚焦点的最大距离
public float minDistance = 2.5f; //摄像机距离实际聚焦点的最小距离
 
public float xSpeed = 250.0f; //横向移动速度(eulerAngles.y)
public float ySpeed = 120.0f; //纵向移动速度(eulerAngles.x)
 
public float yMinLimit = -20; //摄像机仰角(eulerAngles.x)最小值
public float yMaxLimit = 80; //摄像机仰角(eulerAngles.x)最大值
 
public float zoomRate = 20; //推拉摄像机的速度
 
public float rotationDampening = 2.0f; //摄像机移动阻尼              //数值越小摄像机停止的速度越慢, 数值越高停止的速度越快
 
private float x = 0.0f; //水平旋转角度
private float y = 0.0f; //仰角旋转角度
 
private float xDampMove=0;//水平旋转阻尼速度
private float yDampMove=0;//仰角旋转阻尼速度
 
private float targetDistance=0;
 
 
void Awake () {
    Vector3 angles = transform.eulerAngles;
    x = angles.y;
    y = angles.x;
 
       // Make the rigid body not change rotation
       //防止刚体影响物体旋转
       if (GetComponent<Rigidbody>())
              GetComponent<Rigidbody>().freezeRotation = true;
             
       targetDistance=distance;
}
 
//摄像机位移应该在所有其他物体计算之后处理            //LateUpdate 晚于 Update
//防止摄像机移动后有其他物体移动道遮挡的位置, 或者与目标物体位移不同步
void LateUpdate () {
   if(!target)
      return;
      
       // If either mouse buttons are down, let them govern camera position
       //鼠标点击移动摄像机
       if(Input.GetMouseButton(2) || Input.GetMouseButton(1)){
              xDampMove=Input.GetAxis("Mouse X") * xSpeed;
              yDampMove=Input.GetAxis("Mouse Y") * ySpeed;
       } 
      
       // move cam using arrow keys
       //使用键盘移动摄像机
       //~xDampMove-=(xDampMove<xSpeed/2f)?(Input.GetAxis("Horizontal")*xSpeed*0.25f):0;
       //~ yDampMove-=(xDampMove<xSpeed/2f)?(Input.GetAxis("Vertical")*ySpeed*0.25f):0;
      
       //clamp speed
       //限制移动速度最大值
       xDampMove=Mathf.Clamp(xDampMove,-xSpeed,xSpeed);
       yDampMove=Mathf.Clamp(yDampMove,-ySpeed,ySpeed);
      
       //apply
       //施加摄像机移动
       x+=xDampMove*Time.deltaTime;
       y-=yDampMove*Time.deltaTime;
      
       //distance change
       //更改摄像机与目标之间的距离
       if(Input.GetKey(KeyCode.Q))
              distance-=zoomRate*0.25f*Time.deltaTime;
      
       if(Input.GetKey(KeyCode.E))
              distance+=zoomRate*0.25f*Time.deltaTime;
      
       distance -= (Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime) * zoomRate * Mathf.Abs(distance);
       distance = Mathf.Clamp(distance, minDistance, maxDistance);
   
       //缩放施加阻尼
       targetDistance=Mathf.Lerp(targetDistance,distance,2*Time.deltaTime);
      
       //限制仰角
       y = ClampAngle(y, yMinLimit, yMaxLimit);
   
       //calcu
       //计算摄像机的角度和方向
       Quaternion rotation = Quaternion.Euler(y, x, 0);
       Vector3 position= rotation *Vector3.forward * -targetDistance + target.position+new Vector3(0,targetHeight,0);
   
       //slowDown
       //对摄像机的移动施加阻尼
       xDampMove=Mathf.Lerp(xDampMove,0,rotationDampening*Time.deltaTime);
       yDampMove=Mathf.Lerp(yDampMove,0,rotationDampening*Time.deltaTime);
 
      
       //checkLineOfSign and Collision
       //检测是否有碰撞体遮挡视线
       //如果有则移动摄像机的位置到障碍物前面
       position=SignUpdate(target.position+Vector3.up*targetHeight,position,0.3f, distance,0.6f,mask);
      
       //change distance if want
       //更改摄像机位置的同时更改距离    如果需要
       //开启时摄像机离开障碍物遮挡后不会突然跳跃
       //
       targetDistance=Vector3.Distance(position,target.position+Vector3.up*targetHeight);
       //
      
      
       //Apply
       //施加摄像机位移和旋转
       transform.rotation=rotation;
       transform.position=position;
      
}
 
//限制角度
static float ClampAngle (float angle,float min,float max ) {
   if (angle < -360)
      angle += 360;
   if (angle > 360)
      angle -= 360;
   return Mathf.Clamp (angle, min, max);
}
 
//检测是否有碰撞体遮挡在 targetPoint 和 selfPosition 之间
//targetPoint                         目标位置
//selfPosition                 自身位置
//checkRadios                      球星检测区域半径
//maxDis                             最大检测距离
//stepDis                              检测倒碰撞后向前偏移的位置,  建议大于检测半径*2
//s_mask                             碰撞检测遮罩
 Vector3 SignUpdate(Vector3 targetPoint,Vector3 selfPosition,float checkRadios,float maxDis,float stepDis,LayerMask s_mask){
       Ray ray=new Ray(targetPoint,selfPosition-targetPoint);
       RaycastHit hit=new RaycastHit();
      
       if(Physics.SphereCast(ray,checkRadios,out hit,maxDis,s_mask)){
             
              return ray.GetPoint(hit.distance-stepDis);
       }
      
       //无碰撞返回原始位置
       return selfPosition;
}
}

unity摄像机带碰撞检测 摄像机碰到带碰撞物体自动拉近相关推荐

  1. unity 实现了鼠标滚动放大和缩小物体暨拉近拉远相机的效果

    思路是,读取鼠标滚轮的滚动倾向,改变相机的视角域(fieldOfView). 但是,仅仅改变视角域是不行的,因为如果物体在视野边缘,在放大的过程中,也就是视角域缩小的过程中, 物体就可能跑到视野以外去 ...

  2. 【C#】【Unity】第三人称摄像机跟随人物移动时碰撞到墙壁等,摄像机不穿越墙壁

    目前大部分第三人称游戏的摄像机在遇到墙壁等狭隘空间的时候,都选择让摄像机不穿越到墙壁里面,而是让摄像机保持在墙壁表面. 分析情况:(红色方框为摄像机 黑色方框为墙壁) 当前情形摄像机还没达到墙壁摄像机 ...

  3. unity中3dUI或者模型始终面向摄像机,跟随摄像机视角旋转丨视角跟随丨固定视角

    视角跟随 本脚本为一个目标跟随 unity中3dUI或者模型始终面向摄像机,跟随摄像机视角旋转 使用方法超级简单,对于一个资深的Ctrl+cv程序极为友好 不多讲解直接上代码 代码模块 public ...

  4. 【Unity 2D AABB碰撞检测】铸梦之路

    作者介绍:铸梦xy.IT公司技术合伙人,IT高级讲师,资深Unity架构师,铸梦之路系列课程创始人. 目录 1.AABB 碰撞介绍 2.常用2D碰撞盒 3.为什么要学习如何编写碰撞检测 4.2D BO ...

  5. unity中射线碰撞检测总结

    这阵子通过看视频,看书对unity中射线碰撞检测,有了一些了解,这里我把它总结一下写下来,希望能帮助到你们,也希望通过各位大神来指正不足之处: 射线碰撞检测,就是由某一物体发射出一道射线,射线碰撞到物 ...

  6. Android UI(五)云通讯录项目之联系人列表,带侧滑选择,带搜索框

    作者:泥沙砖瓦浆木匠 网站:http://blog.csdn.net/jeffli1993 个人签名:打算起手不凡写出鸿篇巨作的人,往往坚持不了完成第一章节. 交流QQ群:[编程之美 36523458 ...

  7. 在origin 2018中同时画两个图,带errorbar和不带errorbar两种情况

    在origin 2018中同时画两个图,带errorbar和不带errorbar两种情况 在一个图层里同时画两幅图 两幅图坐标可不一致 ①在当前图层中,选中图层左上角的 1 标志 ②右键 1 →图层内 ...

  8. HttpHelps类,用来实现Http访问,Post或者Get方式的,直接访问,带Cookie的,带证书的等方式,可以设置代理...

    原文地址:http://blog.csdn.net/cdefg198/article/details/8315438 万能框架:http://www.sufeinet.com/forum.php?mo ...

  9. UTF-8带BOM和不带BOM的转换

    UTF-8带BOM和不带BOM的转换 标签:Linux UTF-8 BOM [问题] 在linux下如果你使用过的编码不是utf-8你可以使用enca进行转换,然而转换过后的情况是不带bom的uft- ...

  10. androidstudio带pom的上传到jcenter_输送机@网带输送机@304网带输送机@304不锈钢网带输送机@输送机网带厂家定制...

    输送机@网带输送机@食品网带输送机@304网带输送机@304不锈钢网带输送机@输送机网带厂家定制 输送机主要用于运输食品原料或成品.食品输送机根据输送带不同可分为皮带的,链板的,网带的.输送形式有:直 ...

最新文章

  1. b站上java和python视频可以吗_b站有哪些好的java视频?
  2. 动手实现深度学习pytroch版
  3. 携程试点每周两天居家办公反响热烈,76%的员工主动报名
  4. synchronized锁机制 之 代码块锁(转)
  5. Houdini地形与流体解算(模拟泥石流)
  6. acrobat PDF删除部分_pdf转word怎么转教程
  7. 使用J-Link打印日志——SEGGER Real-Time Transfer(RTT)工具的移植使用
  8. 南京大学人工智能学院教授俞扬:我的牛年小结
  9. java根据word书签模板填充数据生成pdf输出
  10. 小强的HTML5移动开发之路
  11. 一次分布式架构cms系统页面静态化模块开发经历
  12. 数据库学习之初见oracle
  13. 201943 ovf 文件的导出和导入
  14. 100/1000BASE-T1多端口测试方案
  15. 五 我们经常会忘记,要学会 走路 才能 奔跑,Python基础教程
  16. 2021Java校招笔试题答案及评分标准
  17. GUI窗口不显示图片背景图片,和布局后不显示组件,的根本原因和解决办法
  18. kernel exploit 有用的结构体
  19. 十三届蓝桥青少组省赛Python-20220423
  20. Android Camera相机开发示例、Android 开发板 USB摄像头采集、定期拍照、定时拍照,安卓调用摄像头拍照、Android摄像头预览、监控,USB摄像头开发、摄像头监控代码

热门文章

  1. 单片机学习-利用intrins.h中的_crol_和_cror_进行流水灯位移
  2. 数字麦克风PDM信号采集与STM32 I2S接口应用(三)
  3. wps右下角弹窗广告(WPS购物或叫WPS热点)彻底关闭
  4. statcounter统计的浏览器市场占有率
  5. 如何利用福禄克OFP2-100-Q CH测试光纤的熔接损耗
  6. 青岛市中小学学籍系统服务器,全国各省市中小学学籍网登录入口
  7. LPC845-BRK开发板运行Blinky示例程序
  8. 周志华揭开机器学习本质的57张PPT
  9. 2021年全球及中国AMOLED行业发展现状、竞争格局及未来发展趋势分析,柔性AMOLED面板将占领市场「图」
  10. 希腊语 - 希腊字母表对应的意思 - 数据挖掘必备