首页 > Unity3D频道 > 【Unity3D研究院之游戏开发】 > Unity3D研究院之处理摄像机跟随避免相机穿墙拉近或透明的方法(四十四)
2013
01-05

Unity3D研究院之处理摄像机跟随避免相机穿墙拉近或透明的方法(四十四)

          当摄像机处于跟随主角状态时,那么主角移动后很有可能摄像机被别的模型挡住。这样用户体验就非常不好,一般3D游戏在处理视角的时候有两种方法,第一种是让被挡住的模型变成透明,第二种是拉近摄像机。前者时候固定视角游戏使用,后者适合变化视角游戏使用。两个我们都学一学蛤蛤。

          如下图所示,MOMO写了一个简单的例子,通过鼠标或触摸来牵引主角向不同的角度移动,旁边有一面墙当主角被这面墙挡住,此时摄像机将拉近。  

    Unity3D研究院之处理摄像机跟随避免相机穿墙拉近或透明的方法(四十四) - 雨松MOMO程序研究院 - 1

 

首先,为了方面鼠标与移动平台上的触摸同时相应我写了一个通用的方法。

包括 开始触摸  触摸中 结束触摸 ,电脑手机都可以用这个方法相应到。

JFConst.cs

 

以前写过一篇文章关于移动主角的,如果对移动主角还有不懂的请看这篇 Unity3D研究院之鼠标控制角色移动与奔跑示例(二十四)  。 这里我就不解释移动主角这部分的代码了。 下面是角色控制器ThirdPersonController.cs 绑定在主角身上。
下面代码中需要详细看的就是161行到174行 ,这部分就是根据触摸屏幕的2D坐标计算主角在3D世界中移动的坐标。

 

如此我们就可以通过鼠标与触摸牵引控制主角移动了,别急这紧紧是开始,下面是本章的要点。

这里我们分析一下摄像机到底什么时候该拉近,什么时候该不拉近。 我的作法是这样的,当角色移动的时候我会从主角身上向摄像机方向发射一条射线,如果射线碰撞到的第一个对象是“摄像机” 那么就标示主角和摄像机之间没有别的模型挡住,此时摄像机就不应该拉近。如果射线碰撞到的第一个对象不是摄像机,那么就标示主角和摄像机之间有别的模型所挡住,此时取得射线与别的模型碰撞的3D坐标接着将“摄像机”的坐标移动到这个坐标上即可。

如下图所示,(红色表示由主角发射到摄像机的射线)主角身后的射线没有被别的模型挡住,射线机不会拉近。

 

Unity3D研究院之处理摄像机跟随避免相机穿墙拉近或透明的方法(四十四) - 雨松MOMO程序研究院 - 2

 

如下图所示,MOMO改变了一下主角的位置,此时主角身后的射向已经被墙挡住,这时把摄像机的坐标移动到被墙挡住点的坐标,这样摄像机就拉近了。

Unity3D研究院之处理摄像机跟随避免相机穿墙拉近或透明的方法(四十四) - 雨松MOMO程序研究院 - 3

 

原理大概就是这样,接着我们学习一下这段代码该如何来写。

MyCamera.cs 挂在射线机上

 

牛头人被墙挡住了,摄像机直接拉近了,小牛头人是不是很帅气?哈哈哈!!

 

Unity3D研究院之处理摄像机跟随避免相机穿墙拉近或透明的方法(四十四) - 雨松MOMO程序研究院 - 4

 

最后雨松MOMO把源码放出来,希望大家学习愉快,哇咔咔。。。

下载地址:http://vdisk.weibo.com/s/mAhiI

 

补充 :摄像机遮挡物体透明。

遮挡透明最简单的办法就是修改材质的透明度,前提需要把材质设置成支持透明通道的 shader Transparent 。 如下图所示,摄像机挡住的那面墙已经成透明状态了。

 

Unity3D研究院之处理摄像机跟随避免相机穿墙拉近或透明的方法(四十四) - 雨松MOMO程序研究院 - 5

 

看看代码是如何写的,把上述代码MyCamera.cs 简单的改一下就可以。 主要是92行到101行。

代码核心就是通过射线得到碰撞模型的材质,然后修改材质的透明度。color.a就是透明度 1是完全不透明,0是完全透明。注意一定是支持透明通道的模型才可以。lastobj是记录上次透明的对象,用于模型透明还原使用。

 

最后,假设你的模型做的非常大,贴图材质也非常的多,你像透明其中一小部分那么上述方法就不合适了,除非把他们都拆出来。我觉得也可以自己写shader实现。我们的项目采用了摄像机拉近的方式。欢迎讨论!!!

 

回答楼下问题:上帝视角代码,看到楼下有朋友问我,那么我就贴出来,其实很简单。下面代码挂在摄像机上, target就是角色对象,distance 是摄像机与角色的距离 height是摄像机与角色的高度。在编辑器中手动调节即可。

 

 

回答问题 :摄像机抖动如何修改

今天微薄上有个朋友问我这样的问题,我在这里解答一下。

来福12345:我又厚颜无耻的来了,您的《Unity3D的研究院之处理摄像机跟随避免相机穿墙拉近或透明的方法(四十四)》对于不规则的物体该怎么弄,我是直接在unity上弄了几个山脉,由于地面凹凸不平,沿着山走的时候发现摄像机会一直透视,而且抖动的很厉害,请问该怎么解决啊

 

1.从设计上避免射线遇到一些复杂的面,如下图所示,红颜色是主角身后的射线,当主角身后的射线碰撞到这样的面,如果此时移动速快快一些摄像机肯定会抖动。 这里最好直接删除Mesh Collider 换成BoxCollider 效率还可以得到提升。产经设计这块我觉得可以参考一下魔兽世界,我在项目中遇到这样问题的地方就是 比较小的门(棱角那种) 或者这样的树。

 

Unity3D研究院之处理摄像机跟随避免相机穿墙拉近或透明的方法(四十四) - 雨松MOMO程序研究院 - 6

 

 

2.但是还有一些比较特殊的地方,如果你的项目必需使用MeshColider 的话 我建议你写触发脚本来修改摄像机,假设 当摄像机被挡住后,变成跟随视角,只到摄像机没被挡住的时候在回到原来视角。

3.我检查了一下上面的代码中我们在加一个判断,应该就可以解决大部分问题、在LateUpdate () 中最后加入代码

 

bool closer 是表示是否拉近。 当摄像机被挡住的时候这个数值等于true;

 

当closer等于假的时候,此时直接修更新摄像机的位置,因为没被挡住。 当closer等于真的时候,摄像机已经被挡住了,我们不修改摄像机的位置,计算摄像机保证不被挡住时,摄像机此时和主角的距离是多少,然后修改distance全局变量即可。当摄像机不被遮挡的时候在恢复之前的距离。 如有问题请留言,我会即时解答。。 谢谢

 

 

//补充/////////

之前的代码还是有点问题,后来我又仔细的重构了一下摄像机的代码。下面的代码在我的项目中已经完美无暇的模拟摄像机拉近了。。 代码对外有两个公有类型, 一个是模型的 一个是模型位置 与头顶的偏移, 因为射线应该是重头顶向后发射的。

 

 

 

雨松MOMO提醒您:亲,如果您觉得本文不错,快快将这篇文章分享出去吧 。另外请点击网站顶部彩色广告或者捐赠支持本站发展,谢谢!

--

最后编辑:
作者:雨松MOMO
专注移动互联网,Unity3D游戏开发
捐 赠如果您愿意花10块钱请我喝一杯咖啡的话,请用手机扫描二维码即可通过支付宝直接向我捐款哦。