目录
4.关于射线检测的ScreenToWorldPoint、ScreenPointToRay和ViewportPointToRay
4.2 ScreenPointToRay和ViewportPointToRay
在游戏编程这块我算新人,只会c#,unity软件上还不太熟练,最近做小项目踩了好几个坑,可能在大佬眼里都是小问题甚至弱智问题,但是当时折磨我挺久的,所以打算记一下。
1.物体之间失去物理效果
当时是做一个小球在平面滚动,本来这是很简单的事,加刚体 ,加碰撞器,不勾选trigger,不说滚动,至少在平面上,但是我的小球穿过平面掉下去……我真的会沉默,在网上找了好多,都不知道什么情况,一问原来这个项目分了很多layer层,之前大佬调过unity里的部分属性,重新设置一下立马就好了。
在Edit——>Project settings——>Physics里设置
通常新建项目都会勾选上,表示层与层之间是否碰撞,因为大佬有自己的想法,我对unity不熟悉,就不知道他这里没勾选,导致无法产生物理碰撞。(其实是大佬写代码的规范,先把这些全部取消掉,在代码里手动设层,避免产生一些不必要的碰撞)
2.Debug.Log失效
别说,说就是太蠢了!一开始是测有无OnTriggerEnter,特地加了一个Debug.Log进去,发现一点输出没有,我就纳闷了,因为trigger的条件更简单,我也设置好了,还是没有,我当时就怀疑不会是debug没有输出吧,于是我把Debug.Log放在aweak里,一看确实没有!
然后在控制台到处点,好,发现又是我的问题。
我把这个输出信息点没了……谁懂,搜了一堆物理碰撞失效的答案,发现是基操出错。
3.协程无法停止
这个在网站上看到别人的解决方法,记录一下:
unity学习记录_StopCoroutine无法停止协程问题-CSDN博客
感谢这位大佬!
经过大佬的提点,学会一个小妙招:当B脚本使用A脚本的协程,但不需要等待协程,可以在A脚本中包装一个方法调用协程,然后在A脚本中关闭协程,可以有效避免n个协程无法停止的问题。
即图1不如图2
![](https://i-blog.csdnimg.cn/blog_migrate/d099cbb1723e9bcaf0fbc2d98d24f16d.png)
![](https://i-blog.csdnimg.cn/blog_migrate/6f204e8b0e6c61f78f7baf89564bdbc5.png)
4.关于射线检测的ScreenToWorldPoint、ScreenPointToRay和ViewportPointToRay
做3D项目时,遇到判断是否点击到碰撞体的问题。
目前知道的是两类方法:
一种是用ScreenToWorldPoint(屏幕坐标转世界坐标)找到世界坐标,再发射射线;
另一种则是用Camera自带的ScreenPointToRay(屏幕坐标转射线)和ViewportPointToRay(视口坐标转射线)。
4.1 ScreenToWorldPoint
我一开始使用的是第一种方法,但很快发现,在Orthographic(正交视角)下,是可以正常判断的,但在Perspectiv(透视视角)下就出问题了,所有转换的世界坐标都等于我相机的坐标。
查了一下发现,还是挺多人遇到这个坑,这里贴上官方对ScreenToWorldPoint的描述:
返回的是距相机平面给定距离z处的屏幕坐标,而透视相机在z=0时是汇聚到相机中心点,因此当我在透视镜头下使用该代码:
Camera.Main.ScreenToWorldPoint(Input.mousePosition);
获取到的坐标永远是相机坐标。
解决方法就是给屏幕坐标的z轴设置距离,推荐使用Camera.farClipPlane。
4.2 ScreenPointToRay和ViewportPointToRay
后来我换成这两个方法:
ScreenPointToRay:将屏幕坐标转换成射线。屏幕大小是根据像素变化,范围:左下角(0,0),右上角(像素宽-1,像素高-1)。
ViewportPointToRay:将视口坐标转换成射线。屏幕大小是相对相机所见的屏幕大小的单位化,范围:左下角(0,0),右上角(1,1)。
这两者是相机进行射线检测的快捷方法,与上面ScreenToWorldPoint不同的是,这两个方法忽略z轴坐标,所以不需要额外设定z轴距离,就可以轻松获取射线。
然而,我的项目有一个3D相机设定了TargetTexture(目的是想让3d物体在2d镜头下呈现),但又需要通过点击获取碰撞体,于是问题出现了,设定了TargetTexture的相机发射射线不准确。
我试过ScreenToWorldPoint和ScreenPointToRay,一直不对,我以为是这两个方法还有什么限制,于是尝试ViewportPointToRay方法,终于正确,但当时我不知道原因,只知道使用ViewportPointToRay可以解决问题。
后来我怀疑是设定了TargetTexture导致的,重新查找,才明白原因,此处贴上原文链接,写得很好:Unity解决在摄像机上面设置了TargetTexture后获取屏幕坐标不准的问题
我使用原文提出的挂一个空相机解决了这个问题,非常感谢!