Unity中Camera.ScreenToWorldPoint返回异常值问题咨询
搞定Camera坐标偏差的问题!
嘿,你遇到的这个坐标偏差问题,核心原因其实很简单——你找错了负责坐标转换的相机,还没处理屏幕和RenderTexture的分辨率差异!
先搞懂为啥会错
你用Camera.main来调用ScreenToWorldPoint,但主相机的画面根本没直接显示在屏幕上啊!它是渲染到RenderTexture,然后贴在那个128x72的Quad上,最后是副相机把这个Quad拍下来给用户看的。所以用户看到的“屏幕空间”是副相机的视口,不是主相机的。再加上屏幕分辨率远大于128x72,鼠标坐标是按屏幕尺寸来的,直接用主相机转换,结果肯定跑偏。
一步步解决它
1. 换副相机来做坐标转换
别再用Camera.main了,直接拿你的副相机引用(可以给副相机加个标签,比如"SecondaryCamera",然后用Camera.FindWithTag("SecondaryCamera")获取,或者在Inspector里直接拖给脚本变量)。
2. 把鼠标坐标映射到RenderTexture的尺寸
因为屏幕和RenderTexture的大小不一样,得先把鼠标的屏幕坐标转成和RenderTexture匹配的坐标,再用副相机转成世界坐标。给你个现成的代码示例:
// 先提前获取好这些引用 public Camera secondaryCamera; public RenderTexture mainCameraRenderTexture; public Transform quadTransform; void Update() { if (Input.GetMouseButton(0)) { // 第一步:把屏幕鼠标坐标转成0-1的归一化坐标 Vector2 normalizedMouse = new Vector2( Input.mousePosition.x / Screen.width, Input.mousePosition.y / Screen.height ); // 第二步:转成RenderTexture上的像素坐标 Vector2 rtMousePos = new Vector2( normalizedMouse.x * mainCameraRenderTexture.width, normalizedMouse.y * mainCameraRenderTexture.height ); // 第三步:用副相机转世界坐标,这里要传Z值——副相机到Quad的距离 float zDistance = Vector3.Distance(secondaryCamera.transform.position, quadTransform.position); Vector3 correctedWorldPos = secondaryCamera.ScreenToWorldPoint( new Vector3(rtMousePos.x, rtMousePos.y, zDistance) ); Debug.Log("终于对了的坐标:" + correctedWorldPos); } }
3. 更省事的小技巧
其实还可以直接用视口坐标转换,因为归一化的鼠标坐标本身就是副相机的视口坐标(左下角是(0,0),右上角是(1,1)),这样能少一步转换:
Vector2 viewportMouse = new Vector2( Input.mousePosition.x / Screen.width, Input.mousePosition.y / Screen.height ); float zDistance = Vector3.Distance(secondaryCamera.transform.position, quadTransform.position); Vector3 correctedWorldPos = secondaryCamera.ViewportToWorldPoint( new Vector3(viewportMouse.x, viewportMouse.y, zDistance) );
额外要注意的点
- 如果副相机是正交模式,Z值的影响不大,但还是得设成副相机到Quad的距离;如果是透视模式,这个Z值必须准确,不然坐标还是会错。
- 检查Quad是不是正好在副相机的视口中央,要是Quad位置偏了,可能还要微调坐标偏移。
内容的提问来源于stack exchange,提问作者Evan Ward
相关产品推荐
相关产品推荐

