Unity 游戏开发技巧集锦之制作一个望远镜与查看器摄像机

Unity中制作一个望远镜

本节制作的望远镜,在鼠标左键按下时,看到的视图会变大;当不再按下的时候,会慢慢缩小成原来的视图。游戏中时常出现的狙击手就是使用望远镜的一个例子,如图2-22所示。

 

图2-22  游戏中狙击手所看到的视图

制作望远镜的过程如下:

(1)在Project视图里,创建一个C#脚本文件,命名为TelescopicView。打开这个脚本文件,并在里面添加下面的代码:

  • 01     using UnityEngine;
  • 02     using System.Collections;
  • 03
  • 04     public class TelescopicView : MonoBehaviour
  • 05     {
  • 06              //公有成员
  • 07              public float ZoomLevel = 2.0f;
  • 08              public float ZoomInSpeed = 100.0f;
  • 09              public float ZoomOutSpeed = 100.0f;
  • 10              //私有成员
  • 11              private float initFOV;
  • 12              //脚本初始化时,调用此函数
  • 13              void Start ()
  • 14              {
  • 15                        //获取当前摄像机的视野范围
  • 16                       initFOV = Camera.main.fieldOfView;
  • 17              }
  • 18              //运行游戏时的每一帧,都调用此函数
  • 19              void Update ()
  • 20              {
  • 21                        //当鼠标左键按下时
  • 22                       if (Input.GetKey(KeyCode.Mouse0))
  • 23                       {
  • 24                                 ZoomView();
  • 25                       }
  • 26                       else
  • 27                       {
  • 28                                 ZoomOut();
  • 29                       }
  • 30              }
  • 31              //放大摄像机的视野区域
  • 32              void ZoomView()
  • 33              {
  • 34                       if (Mathf.Abs(Camera.main.fieldOfView - (initFOV / ZoomLevel)) < 0.5f)
  • 35                       {
  • 36                                 Camera.main.fieldOfView = initFOV / ZoomLevel;
  • 37                       }
  • 38                       else if (Camera.main.fieldOfView - (Time.deltaTime * ZoomInSpeed) >= (initFOV / ZoomLevel))
  • 39                       {
  • 40                                 Camera.main.fieldOfView -= (Time.deltaTime * ZoomInSpeed);
  • 41                       }
  • 42              }
  • 43              //缩小摄像机的视野区域
  • 44              void ZoomOut()
  • 45              {
  • 46                       if (Mathf.Abs(Camera.main.fieldOfView - initFOV) < 0.5f)
  • 47                       {
  • 48                                 Camera.main.fieldOfView = initFOV;
  • 49                       }
  • 50                       else if (Camera.main.fieldOfView + (Time.deltaTime * ZoomOutSpeed) <= initFOV)
  • 51                       {
  • 52                                 Camera.main.fieldOfView += (Time.deltaTime * ZoomOutSpeed);
  • 53                       }
  • 54              }
  • 55     }

放大和缩小摄像机的视野区域,依靠的变量是Camera.main.fieldOfView,所以代码32行的ZoomView()和44行的ZoomOut()就是通过改变Camera.main.fieldOfView的大小,进而调节视野区域的大小的。

(2)将脚本TelescopicView添加到Main Camera上,选中后者后,在Inspector视图上查看脚本组件中的各属性,如图2-23所示。Zoom Level可以调节视图能放大到什么程度;Zoom In Speed调节视图的放大速度;Zoom Out Speed调节视图缩小的速度。

 

图2-23  TelescopicView组件上的各属性

(3)运行游戏,当鼠标左键按下时,视图会放大,松开时,视图会慢慢恢复成原来的样子。如图2-24所示。

 

图2-24  视图的放大与缩小

(4)如果读者此时使用的Unity是付费版本的话,还可以把这个望远镜的视图效果做的更形象一些。在Unity里,单击Assets|Import Package|Image Effects(Pro only)命令,导入Image Effects(图像效果)资源包,如图2-25所示。

(5)选中Main Camera,单击Component|Image Effects|Vignette命令,为它添加Vignette(光晕、光损失)组件,如图2-26所示。

 

图2-25  导入Image Effects资源包           图2-26  添加Vignette组件

(6)再次运行游戏。当鼠标左键按下时,望远镜的视图效果更逼真了(添加了光晕的效果),如图2-27所示。

 

图2-27  望远镜视图的放大与缩小

Unity中制作一个查看器摄像机

如果是一个侦探类的游戏,在侦探找到一个可疑物品时,总会四下打量这个物品,有时还会拿着放大镜放大一些细节的地方。而本节要制作的查看器摄像机,就模拟了这一过程,它的操作类似于在Scene视图上对游戏对象所做的旋转和缩放操作。制作步骤如下:

(1)在Project视图里,创建一个C#脚本文件,命名为InspectCamera。打开这个脚本文件,并在里面添加下面的代码:

  • 01     using UnityEngine;
  • 02     using System.Collections;
  • 03     //添加一个菜单项
  • 04     [AddComponentMenu("Camera-Control/Inspect Camera")]
  • 05     public class InspectCamera: MonoBehaviour
  • 06     {
  • 07              //公有成员
  • 08              public Transform target;                               //查看器摄像机查看的目标对象
  • 09              public float distance= 10.0f;                         //摄像机与目标对象间的距离
  • 10              public float xSpeed= 250.0f;                        //横向旋转目标对象时的速度
  • 11              public float ySpeed= 120.0f;                        //纵向旋转目标对象时的速度
  • 12              public float yMinLimit= -20.0f;                     //纵向旋转目标对象时的范围(最小值)
  • 13              public float yMaxLimit= 80.0f;                     //纵向旋转目标对象时的范围(最大值)
  • 14              public float zoomInLimit= 2.0f;                            //最大的方法倍数
  • 15              public float zoomOutLimit= 1.0f;                //最小的缩小倍数
  • 16              //私有成员
  • 17              private float x= 0.0f;
  • 18              private float y= 0.0f;
  • 19              private float initialFOV;
  • 20              //脚本初始化时调用
  • 21              void Start ()
  • 22              {
  • 23                       initialFOV = camera.fieldOfView;
  • 24                       transform.position = new Vector3(0.0f, 0.0f, -distance) + target.position;
  • 25                       Vector3 angles= transform.eulerAngles;
  • 26                       x = angles.y;
  • 27                       y = angles.x;
  • 28                        if (rigidbody)
  • 29                                 rigidbody.freezeRotation = true;
  • 30              }
  • 31              //在每帧即将结束时调用
  • 32              void  LateUpdate ()
  • 33              {
  • 34                        //按下鼠标左键时
  • 35                       if (target && Input.GetMouseButton(0))
  • 36                       {
  • 37                                 //按下键盘左边的Shift,或者右边的Shift
  • 38                                 if(Input.GetKey(KeyCode.RightShift) || Input.GetKey(KeyCode.LeftShift))
  • 39                                 {
  • 40                                          float zoom= camera.fieldOfView - Input.GetAxis ("Mouse Y");
  • 41                                          if(zoom >= initialFOV / zoomInLimit && zoom <= initialFOV / zoomOutLimit)
  • 42                                          {
  • 43                                                    //改变摄像机视图的大小
  • 44                                                   camera.fieldOfView -= Input.GetAxis ("Mouse Y");
  • 45                                          }
  • 46                                 }
  • 47                                 else
  • 48                                 {
  • 49                                          x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
  • 50                                          y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
  • 51                                 }
  • 52                                 y = ClampAngle(y, yMinLimit, yMaxLimit);
  • 53                                 Quaternion rotation= Quaternion.Euler(y, x, 0);
  • 54                                 Vector3 position= rotation * new Vector3(0.0f, 0.0f, -distance) + target.position;
  • 55                                 //修改旋转度和位置
  • 56                                 transform.rotation = rotation;
  • 57                                 transform.position = position;
  • 58                       }
  • 59              }
  • 60              //旋转的角度范围
  • 61              static float  ClampAngle ( float angle ,   float min ,   float max  )
  • 62              {
  • 63                       if (angle < -360.0f)
  • 64                                 angle += 360.0f;
  • 65                       if (angle > 360.0f)
  • 66                                 angle -= 360.0f;
  • 67                       return Mathf.Clamp (angle, min, max);
  • 68              }
  • 69     }

(2)将脚本InspectCamera添加到Main Camera上,选中后者,在查看器中查看脚本组件中的各属性,如图2-28所示。各属性的意义在脚本的08~15行有注释说明,这里不再重复。

注意:需要给Target属性赋予一个明确的游戏对象,本示例赋予的是Capsule(胶囊),如图2-29所示。

 

图2-28  添加到Main Camera上的脚本组件中的各属性         图2-29  场景中的Capsule对象

(3)为游戏场景添加Directional light,并保证此对象上光的照射方向与摄像机的视图方向一致,这会使得摄像机的视图,所呈现的对象的正面是被照亮的。然后在Hierarchy视图里拖动Directional light到Main Camera,使前者称为后者的子对象,如图2-30所示。如此一来,Directional light就会随着Main Camera的移动而移动。最后达到的效果,就像是人物角色的帽子上有手电筒,人往哪里看,光就往哪里照;人走到哪里,光就跟到哪里。

 

图2-30  Directional light与Main Camera的设置

(4)运行游戏,在Game视图里,按下鼠标左键并移动,视图会绕着目标对象移动;按下鼠标的同时按下键盘上的Shift键,上下移动鼠标可以放大和缩小视图所看到的目标对象,如图2-31所示。

 

图2-31  查看器摄像机运行效果

本文选自:Unity 游戏开发技巧集锦大学霸内部资料,转载请注明出处,尊重技术尊重IT人!

Unity 游戏开发技巧集锦之制作一个望远镜与查看器摄像机的更多相关文章

  1. Unity 游戏开发技巧集锦之使用cookie类型的纹理模拟云层的移动

    Unity 游戏开发技巧集锦之使用cookie类型的纹理模拟云层的移动 使用cookie类型的纹理模拟云层的移动 现实生活中,当阳光直射大地,而天空中又有很多云时,云层的影子总是会投射在大地上,风吹着 ...

  2. Unity 游戏开发技巧集锦之创建透明的材质

    Unity 游戏开发技巧集锦之创建透明的材质 Unity创建透明的材质 生活中不乏透明或者半透明的事物.例如,擦的十分干净的玻璃,看起来就是透明的:一些塑料卡片,看起来就是半透明的,如图3-23所示. ...

  3. Unity 游戏开发技巧集锦之创建部分光滑部分粗糙的材质

    Unity 游戏开发技巧集锦之创建部分光滑部分粗糙的材质 创建部分光滑部分粗糙的材质 生活中,有类物体的表面既有光滑的部分,又有粗糙的部分,例如丽江的石板路,如图3-17所示,石板的表面本来是粗糙的, ...

  4. Unity 游戏开发技巧集锦之材质的应用的创建反射材质

    Unity 游戏开发技巧集锦之材质的应用的创建反射材质 Unity中材质的应用 游戏中,大多数材质的应用都离不开纹理,而纹理本身是图片.所以,在学习本章时,最好在电脑上安装一个可以编辑图片的功能强大的 ...

  5. Unity 游戏开发技巧集锦之使用忍者飞镖创建粒子效果

    Unity 游戏开发技巧集锦之使用忍者飞镖创建粒子效果 使用忍者飞镖创建粒子效果 游戏中,诸如烟.火.水滴.落叶等粒子效果,都可以使用粒子系统(particle system)来实现.例如,<明 ...

  6. Re:Unity游戏开发有哪些让你拍案叫绝的技巧?

    这是我在知乎一个问题: <Unity游戏开发有哪些让你拍案叫绝的技巧?> 下面的回答,觉得蛮有趣的,贴在这里和博客的朋友们分享下. ----- 分享一个比较好玩的内容吧. 大家都知道Uni ...

  7. 关于Unity游戏开发方向找工作方面的一些个人看法

     这是个老生常谈,却又是谁绕不过去的话题,而对于每个人来说,所遇到的情况又不尽相同,别人的求职方式和路线不一定适合你,即使是背景很相似的两个人,有时候机遇也很重要. 我本人的工作经验只有一年,就业方式 ...

  8. C# Unity游戏开发——Excel中的数据是如何到游戏中的 (四)2018.4.3更新

    本帖是延续的:C# Unity游戏开发--Excel中的数据是如何到游戏中的 (三) 最近项目不算太忙,终于有时间更新博客了.关于数据处理这个主题前面的(一)(二)(三)基本上算是一个完整的静态数据处 ...

  9. 2017年Unity游戏开发视频教程(入门到精通)

    本文是我发布的一个Unity游戏开发的学习目录,以后我会持续发布一系列的游戏开发教程,都会更新在这个页面上,适合人群有下面的几种: 想要做独立游戏的人 想要找游戏开发相关工作的人 对游戏开发感兴趣的人 ...

随机推荐

  1. CF540 B 贪心

    坑在B题是常态,弱智的日常. 是找中位数不是平均值. 慌了,乱写了 出了一塌糊涂的ZZ代码 特记一下 /** @Date : 2017-08-27 17:25:11 * @FileName: B.cp ...

  2. LightOJ 1244 - Tiles 猜递推+矩阵快速幂

    http://www.lightoj.com/volume_showproblem.php?problem=1244 题意:给出六种积木,不能旋转,翻转,问填充2XN的格子有几种方法.\(N < ...

  3. Anagrams by Stack(深度优先搜索)

    ZOJ Problem Set - 1004 Anagrams by Stack Time Limit: 2 Seconds      Memory Limit: 65536 KB How can a ...

  4. CSS基础复习

    重新撸一遍CSS的基础,因为以前面试的时候被问到,突然发现某些概念搞不清楚,瞬间懵逼了,其实我都知道的,就是因为不会炒概念,导致面试官觉得我很low,你特么连这个都不知道还敢来面试,回家种田去好嘛! ...

  5. Stat1—浅谈协方差矩阵

    今天看论文的时候又看到了协方差矩阵这个破东西,以前看模式分类的时候就特困扰,没想到现在还是搞不清楚,索性开始查协方差矩阵的资料,恶补之后决定马上记录下来,嘿嘿~本文我将用自认为循序渐进的方式谈谈协方差 ...

  6. 【洛谷 P3199】 [HNOI2009]最小圈(分数规划,Spfa)

    题目链接 一开始不理解为什么不能直接用\(Tarjan\)跑出换直接求出最小值,然后想到了"简单环",恍然大悟. 二分答案,把所有边都减去\(mid\),判是否存在负环,存在就\( ...

  7. 39、请用代码简答实现stack

    栈和队列是两种基本的数据结构,同为容器类型.两者根本的区别在于: stack:后进先出 queue:先进先出 PS:stack和queue是不能通过查询具体某一个位置的元素而进行操作的.但是他们的排列 ...

  8. 去除IE10+上文本框巨丑无比的删除图标以及显示密码图标

    去除IE10+上文本框巨丑无比的删除图标以及显示密码图标 IE浏览器总是让人喜欢让人厌,在最新的IE浏览器(IE10+)上使用表单时,文本框内后面会出现很巨丑无比的“删除图标”以及“显示密码图标”,如 ...

  9. docker 加速

    Docker配置阿里云加速地址 打开阿里云网站https://cr.console.aliyun.com,登陆自己的阿里云账号. 然后只需要在服务器配置docker配置文件,只需要修改"Ex ...

  10. [ python ] 练习作业 - 3

    1. 写出Python查找一个变量的顺序 提示:4中作用域的顺序 本地作用域(local) --> 当前作用域被嵌入的本地作用域(enclsing locals) --> 全局/模块作用域 ...