实现类似摄像头,遇到遮挡物自动拉近拉远视距,不被遮挡物遮盖人物的效果

  • 效果图
    • 一、简介
    • 二、基本层级
    • 三、核心脚本
    • 四、寒暄

效果图

传入的时gif图,帧率有所降低,不过能看清楚
这是旋转时的效果

这是背后有墙时的效果

一、简介

全部代码放上来太麻烦了,就只把挂载核心的代码拿出来,代码中不知道是干什么的请自动忽略,其余用到与主题相关的代码都有注释,有需要解释的地方可以留言,废话不多说,客官往下看。

二、基本层级

这个脚本是挂在人物下面用来设置摄像机位置的一个空物体上的,层次结构是这样的:

在代码中的位置:
物体:脚本变量名称
1.Main Camera :private GameObject MainCamera

  • 摄像机身上没有脚本,使用vector3.SmoothDamp()来跟随cameraPos,这样设置,就可以达到很多游戏上摄像平滑移动的效果。
//设置摄像机跟随MainCamera.transform.position = Vector3.SmoothDamp(MainCamera.transform.position, transform.position, ref RefCameraForWorld,CameraWorldSpreed);

2.PlayerHand :private GameObject PlayerHand
这个是人物的父物体
3.cameraHand : private GameObject CameraHand
这个是摄像机的父物体,放在人物的头顶,以下几个作用:

  • 使用LookAt函数使摄像机啊始终看向这个物体
- MainCamera.transform.LookAt(CameraHand.transform);   //摄像机始终看向人物
  • 再有就是用来控制摄像机的上下角度的限制和旋转,因为摄像机的位置是这个物体的子物体,所以只要旋转这个物体的X轴也就是旋转了上下的视角,这样更方便的去限制上下角度的大小,代码中用来pi点的所有代码可以理解为键盘操作部分,比如WSAD,详细可以去看[傅老師/Unity教學][4/27中午更新] DarkSouls複刻經典教程#第一季,剩下的horizontalSpeed、verticalSpeed就是鼠标的X轴和Y轴的速度,鼠标XY轴的设置不在这个脚本,就是这两条,请记住这两个命名下面会用pi点出来:
Jup = Input.GetAxis("Mouse Y") * MouseSpeedX;
Jright = Input.GetAxis("Mouse X") * MouseSpeedY;
  • 这个就是鼠标控制左右和上下旋转的代码
//计算摄像机的旋转private void CalculateCameraRotate(){PlayerHand.transform.Rotate(Vector3.up, pi.Jright * horizontalSpeed * Time.fixedDeltaTime);tempEulerX -= pi.Jup * verticalSpeed * Time.fixedDeltaTime;tempEulerX = Mathf.Clamp(tempEulerX, CameraXMin, CameraXMax);CameraHand.transform.localEulerAngles = new Vector3(tempEulerX, 0, 0);}

4.CameraPos : 基本都是this.transfrom
接下来就是挂载下面脚本的物体

三、核心脚本

```csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;public class CameraController : MonoBehaviour {[Header("===== 摄像机输入值 =====")]public float horizontalSpeed = 100f;            //摄像机水平移动速度public float verticalSpeed = 80f;               //摄像机垂直移动速度public float MouseCenterSpeed = 200f;           //摄像机中键速度public float tempEulerX;                        //限制摄像机上下角度public float CameraWorldSpreed;                 //摄像机跟随速度public float SaveCameraCenter;                  //储存摄像机的中键值public float CameraRotateMax = 3;               //最远的摄像机距离public float CameraRotateMin = 0.7f;            //最近的摄像机距离public float CameraXMin = -25;                  //最大向下角度public float CameraXMax = 30;                   //最大向上角度public float distance = 3;                      //当前使用的距离private float Mouse2Distance = 3;               //鼠标中键滚动了多少private bool IsMouse2 = true;                   //是否允许缩放摄像机[Header("===== 组件 =====")]public LineRenderer line;                       //画出射线//public LineRenderer line2;                    //画出射线private PlayerInput pi;                         //人物输入脚本private GameObject PlayerHand;                  //玩家碰撞体积private GameObject CameraHand;                  //摄像机父亲private GameObject MainCamera;                  //主摄像机public GameObject model;                        //玩家自身private Vector3 RefCameraForWorld;             //暂存摄像机的缓动值private Vector3 TempVec;                       //射线时暂存摄像机位置private Vector3 Offsetpos;                     //摄像机与人物之间的差值private void Awake(){CameraHand = transform.parent.gameObject;PlayerHand = CameraHand.transform.parent.gameObject;pi = PlayerHand.GetComponent<PlayerInput>();MainCamera = GameObject.FindGameObjectWithTag("MainCamera");model = pi.GetComponent<ActorController>().model;}private void Start(){//计算出摄像机与人物之间的差值Offsetpos = transform.position - CameraHand.transform.position;}private void FixedUpdate(){//获取人物的欧拉角//(这个是和FixedUpdate最后一句//当前人物的欧拉角对应的,//作用是现将人物的方向保存下来,在做完摄像机的一切操作后在赋值给人物)Vector3 TempModleEuluer = model.transform.eulerAngles;//设置摄像机跟随MainCamera.transform.position = Vector3.SmoothDamp(MainCamera.transform.position, transform.position, ref RefCameraForWorld, CameraWorldSpreed);MainCamera.transform.LookAt(CameraHand.transform);                               //摄像机始终看向人物//调用射射线计算摄像机与人物之间的距离CalculateCameraDistance();//设置这个的原因:为了保存人物滚轮滚动的距离,也在不滚动滚轮时不用一直去计算摄像机与人物之间的距离if (Input.GetAxis("Mouse ScrollWheel") != 0){CalculateCameraCenter();}//限制摄像机的自动旋转,这个设置成input.mouseButton(1)也可以if (pi.IsCameraMouseEnable){//按下鼠标右键后去调用摄像机旋转的方法//并且重新计算差值CalculateCameraRotate();Offsetpos = transform.position - CameraHand.transform.position;}//否则就将当前位置确定下来else{transform.position = Offsetpos + CameraHand.transform.position;}//当前人物的欧拉角(与FixedUpdate第一行代码呼应,上面写了)model.transform.eulerAngles = TempModleEuluer;}//计算摄像机的旋转private void CalculateCameraRotate(){PlayerHand.transform.Rotate(Vector3.up, pi.Jright * horizontalSpeed * Time.fixedDeltaTime);tempEulerX -= pi.Jup * verticalSpeed * Time.fixedDeltaTime;tempEulerX = Mathf.Clamp(tempEulerX, CameraXMin, CameraXMax);CameraHand.transform.localEulerAngles = new Vector3(tempEulerX, 0, 0);}//发射射线计算摄像机与人物之间的距离private void CalculateCameraDistance(){Ray ray2 = new Ray(CameraHand.transform.position, (this.transform.position - CameraHand.transform.position).normalized);RaycastHit hit2;int laymask = ~(1 << 10);if (Physics.Raycast(ray2, out hit2, 100, laymask)){IsMouse2 = false;if (hit2.distance < Mouse2Distance ){line.SetPositions(new Vector3[] { CameraHand.transform.position, hit2.point });if (hit2.distance < CameraRotateMin){CrameraPosition(CameraRotateMin);return;}CrameraPosition(hit2.distance);}else{CrameraPosition(Mouse2Distance);IsMouse2 = true;}}else if ( hit2.distance == 0){CrameraPosition(Mouse2Distance);IsMouse2 = true;}transform.position = Offsetpos + CameraHand.transform.position;}//计算摄像机应该拥有的位置private void CrameraPosition( float theDistance){//1.设置摄像机的位置this.Offsetpos = this.Offsetpos.normalized * theDistance;}//计算鼠标中键调整摄像机的远近private void CalculateCameraCenter(){if (EventSystem.current.IsPointerOverGameObject() != false){return;}distance = Offsetpos.magnitude;distance -= Input.GetAxis("Mouse ScrollWheel") * MouseCenterSpeed;distance = Mathf.Clamp(distance, CameraRotateMin, CameraRotateMax);if (Input.GetAxis("Mouse ScrollWheel") != 0){Mouse2Distance = distance;}Offsetpos = Offsetpos.normalized * distance;}}

四、寒暄

呃………………没啥说的了,代码逻辑还不是很好,看不懂给我留言,有更好的建议也希望能留言。谢谢。
对这块比较感兴趣的推荐学习[傅老師/Unity教學][4/27中午更新] DarkSouls複刻經典教程#第一季,大部分逻辑都是跟着学的。

unity实现吃鸡摄像头,自动拉近拉远视距,不被遮挡物遮盖人物效果相关推荐

  1. Unity 相机的移动旋转以及拉近拉远的原理

    不管是在游戏(如超级玛丽游戏)中,还是在工艺仿真中,还是在手机app开发中,相机都是必不可少的模块,本篇文章重点讲解一下相机背后的原理 下面这幅图引入两个角色,第一就是我们需要控制的相机,第二就是相机 ...

  2. Unity的摄像机拉近拉远和旋转脚本实现

    摄像机是Unity3d里面一定要用到的.所以熟悉摄像机的使用也是能掌握unity3d的基础. 这里详细介绍一个摄像机脚本,脚本的功能类似与魔兽争霸的鼠标滚轮拉近拉远以及按住右键移动鼠标旋转视野. 涉及 ...

  3. unity鼠标控制镜头旋转_unity3D鼠标滚轮来实现镜头拉近拉远及视角旋转

    镜头拉近拉远的代码(无限拉远拉近) 代码如下: if( Input.GetAxis("Mouse ScrollWheel") != 0 ) { this.gameObject.tr ...

  4. unity实现镜头拉近拉远的方式

    首先获取相机对象: //camera = GetComponent<Camera>(); //脚本在相机对象上//GameObject.FindWithTag("MainCame ...

  5. Unity 镜头拉近拉远 和旋转视角

    自己使用的是 Unity2018和VS2019版. 向主相机添加FollowPlayer类. 下面呈现代码 这里有小Bug, 拉近拉远和旋转视角无法同时使用,后续会进行更改完善 public clas ...

  6. Unity 实现简单的相机跟随和鼠标滚轮拉近拉远视野

    1.脚本挂载在Main Camera 上 ,相机跟随的实现主要是让相机的位置和玩家的位置的差值始终保持不变. 2.实现鼠标滚轮拉近拉远视野,要先测试一下自己鼠标滚轮前滑后滑的正负值,每个鼠标不一定相同 ...

  7. unity实现摄像机拉近拉远视野

    近期做项目时遇到需要实现摄像机视野拉近拉远的效果 用鼠标滚轮实现摄像机视野拉近拉远 代码如下: private float mouseX; private float mouseY; void Upd ...

  8. 航拍拉近拉远镜头_什么是远摄镜头?

    航拍拉近拉远镜头 Telephoto lenses can be incredibly useful, but how is it different from other lenses, and w ...

  9. iOS 扫描二维码实现手势拉近拉远镜头

    在做扫码需求,往往会有放大镜头需求. 苹果提供了AVCaptureConnection中,videoScaleAndCropFactor:缩放裁剪系数,使用该属性,可以实现拉近拉远镜头.再结合手势UI ...

最新文章

  1. 第二阶段个人冲刺第一天总结
  2. tp_link路由器 重新设置
  3. C++11 右值引用、移动语义、完美转发、万能引用
  4. mysql pom.xml版本号_maven的pom.xml的依赖,什么情况下可以不写版本号?
  5. 深度学习(三十八)卷积神经网络入门学习(2.0)
  6. iPhone 6S GPU到底多强
  7. 数据科学入门与实战:玩转pandas实战项目分析航班晚点情况
  8. html余下的高度,html – 使第二行的弹性项目占据容器的剩余高度
  9. python代码编辑教程_python教程:pycharm编写代码的方式教学
  10. 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_05 IO字符流_9_JDK7和JDK9流中异常的处理...
  11. Myeclipse8.5 最新注册码以使用方法(可以用到2015年!!!)
  12. arcgis desktop 地理编码服务发布
  13. PowerDesigner 报错 Could not Initialize JavaVM!
  14. java语言的特点_Java语言有什么特点?
  15. Golang系列(四)之面向接口编程
  16. 消灭害虫V1.0 | EliminatePests V1.0
  17. MySQL时区问题(与北京时间相差13小时)-- mybatisplus使用LocalDateTime.now()获取系统当前时间问题
  18. 外省职称计算机,外地职称在当地是否可以用?
  19. 置换和轮换(新姿势,摘自黑书)
  20. 学习php开发难吗,PHP开发自学难吗,PHP自学要多长时间?

热门文章

  1. 美国项目管理协会宣布从Net Objectives手中收购FLEX
  2. 算法 - 希尔排序(Shell Sort)
  3. 华为电脑无法打开热点,点击按钮之后手机搜索不到怎么办?
  4. 一般正态分布如何转化为标准正态分布?
  5. 论文解读:Few-shot Slot Tagging with Collapsed Dependency Transfer and Label-enhanced Task-adaptive Proje
  6. day14 方法原则 方法命名 方法组成 方法重载
  7. 自己搭建一个内网穿透服务,用域名访问自己家服务器的网站
  8. java获得当前时间一小时前的时间
  9. 4、综合布线系统的施工教程讲解
  10. HTPC知识普及第二讲