creator3.3版本camera.screenToWorld计算结果出错

  • Creator 版本:3.3

我正在将项目从2.4.6升级到3.3, 其中Camera接口 getScreenToWorldPoint -> screenToWorld有变更,变更好了之后发现新接口screenToWorld求出的值不正确。

在creator2.4版本中,用getScreenToWorldPoint或者直接用camera._camera.screenToWorld(new cc.Vec3(), cc.v3(900, 300, 0.2), cc.visibleRect.width, cc.visibleRect.height)求出的世界坐标会正确显示在屏幕上,即使相机旋转移动也没问题。

而在creator3.3版本中,用camera.screenToWorld(out, new Vec3(posx, posy, posz))求出的值完全不在屏幕范围,而且相机旋转之后,求出的世界坐标也完全相同。

1赞

最后一句话我有理由怀疑你场景里有两个摄像机,而且你用的camera一直不是你想用的那一个

我单做了一个测试场景,只有1个相机,1个模型测的。
2.4版已经线上运营了,升3.3看不见怪物才发现的问题。

传个测试样例
CameraBug.rar (398.3 KB)

let p = this.getComponent(cc.Camera).screenToWorld(screenPos, out)

out 是第二个参数,你参数反了

3.3的文档,在新建ts文件的时候有注释

https://docs.cocos.com/creator/3.3/api/en/#/

我这么用是因为引擎代码Creator\3.3.0\resources\resources\3d\engine\cocos\core\renderer\scene\camera.ts里定义的是
/**
* transform a screen position (in oriented space) to world space
*/
public screenToWorld (out: Vec3, screenPos: Vec3): Vec3 {…}
实际我测试时
screenToWorld(screenPos, out),screenToWorld(out,screenPos),screenToWorld(screenPos, screenPos)我全部都试了皆不能输出正确的值

1赞

用this.getComponent(cc.Camera).screenToWorld(screenPos, out)测试

//摄像机x轴角度:0, Fov:10 0 190 0.9 ‘==============>’ -0.9001 -0.07392125603864737 1.8991000000000007

//摄像机x轴角度:30,Fov:10 0 190 0.9 ‘==============>’ -0.9001 -0.07392125603864737 1.8991000000000007

//摄像机x轴角度:0, Fov:45 0 190 0.9 ‘==============>’ -0.9001 -0.07392125603864737 1.8991000000000007

//摄像机x轴角度:30,Fov:45 0 190 0.9 ‘==============>’ -0.9001 -0.07392125603864737 1.8991000000000007

可以看到摄像机变化之后,取值完全不变,自然落到屏幕的位置也千奇百怪。

1赞

相机怎么转,其空间坐标是不会变的,我估计 你想要做的,应该是取到这个out坐标后减相机空间坐标得到向量,然后normalize后乘上距离得到相机前的实际空间位置
你实际想要的估计是这个位置

我不该拉上旋转一起说,现在的矛盾点就是:

creator2.4版本 getScreenToWorldPoint(new Vec3(300,300,0.6)) 得到的结果是 {x: -202.6823206579692, y: -15.141660214229114, z: -584.8832231365925}

creator3.3版本 screenToWorld(new Vec3(300,300,0.6)) 得到的结果是 {x: 0.24425652173914048, y: 0.26974492753623186, z: 0.6003999999999999}

相机角度位置fov等都一样。

解释下相机转动那里的意思:
通过屏幕坐标获取世界坐标(getScreenToWorldPoint)是根据摄像机上的坐标取得世界坐标系上的点,摄像机旋转一定角度,摄像机上的点在世界坐标系上就会变化。

例如在creator2.4上:
摄像机x轴0度取值 getScreenToWorldPoint: -202.6823206579692 -15.141660214229114 -584.8832231365925
摄像机x轴30度取值 getScreenToWorldPoint: -202.68232065795817 279.3285491672865 -514.0945595906982
可以看到世界坐标值发生了变化

而在creator3.3上
摄像机x轴0度取值 screenToWorld: 0.24425652173914048 0.26974492753623186 0.6003999999999999
摄像机x轴30度取值 screenToWorld: 0.24425652173914048 0.26974492753623186 0.6003999999999999
可以看到值就没变

我不知道3.3是不是有新的框架原理去进行坐标转换,但我们2.4用的方法现在肯定是不起效了。

问题在于组件start后不生效,要等一会才生效。

直接运行
::::: 300 300 1 ===========>> -0.330357142857143 0.4492753623188406 1

延迟3秒运行
::::: 300 300 1 ===========>> -64.47328116829001 -679.3128877815868 -134.90067459144177

延迟之后就能正确计算了

screenToWorld对于这个我也摸不着头脑,我用geiLocal获得触点去转换正常,用和2.4相同的getUILocal获得触点就不正常了。我干脆手动去算,不用这个api了

该主题在最后一个回复创建后14天后自动关闭。不再允许新的回复。