Unity - Camera ScreenToWorldPoint返回奇数值

时间:2018-05-02 12:50:49

标签: c# unity3d

主相机的输出设置为渲染纹理,应用于材质,应用于缩放至128x72的四边形。辅助摄像机设置为仅查看渲染到子四元组的内容,该四元组具有包含渲染纹理的材质。

然而,Camera.main.ScreenToWorldPoint(Input.mousePosition)返回的值甚至不接近GameObject。 I.E. GameObject(0, 0, 0)处实例化,将鼠标悬停在(307, 174)上会显示鼠标。将Rotating Object移动到屏幕的右边缘只会返回64位的x位置(128px宽四边形的一半),因此我不确定300+的来源。不确定四/相机设置是否对此负责。

编辑:使用单个正交相机,除了使用渲染纹理之外,所有属性都相同,而不是我现在拥有的设置会产生准确的ScreenToWorldPoint输出。

enter image description here enter image description here enter image description here enter image description here

4 个答案:

答案 0 :(得分:2)

Input.mousePosition属性仅返回鼠标位置的x和y轴(以像素为单位)。

ScreenToWorldPoint也需要z轴,Input.mousePosition无法提供。 z轴值应该是摄像机的nearClipPlane。它会给你一个位于相机前面的位置。

根据要实例化按下鼠标按钮的3D对象的大小,您需要对其应用偏移以使其对屏幕完全可见。对于在Unity中创建的简单立方体,2的偏移量很好。如果比这更大,你需要增加偏移量。

以下是如何正确使用ScreenToWorldPoint Camera.nearClipPlaneoffset来实例化点击鼠标的3D对象的完整示例:

public GameObject prefab;
public float offset = 2f;

void Update()
{
    if (Input.GetMouseButtonDown(0))
    {
        Camera cam = Camera.main;

        Vector2 mousePos = Vector3.zero;

        mousePos.x = Input.mousePosition.x;
        mousePos.y = Input.mousePosition.y;

        Vector3 worldPoint = cam.ScreenToWorldPoint(new Vector3(mousePos.x, mousePos.y, cam.nearClipPlane + offset));

        Instantiate(prefab, worldPoint, Quaternion.identity);
    }
}

答案 1 :(得分:1)

您可能无法正确调用Camera.ScreenToWorldPoint方法。特别是,传递给该方法的屏幕位置参数的z位置应该被定义为来自摄像机的世界单位。请参阅Unity documentation on Camera.ScreenToWorldPoint

而不是Camera.main.ScreenToWorldPoint(Input.mousePosition),我认为这是调用Camera.ScreenToWorldPoint的正确方式:

var cameraPosition = Camera.main.transform.position;

// assuming `transform` is the transform "Virtual Screen Quad"...
float zWorldDistanceFromCamera = transform.position.z - cameraPosition.z;

var screenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, zWorldDistanceFromCamera);
var worldPoint = Camera.main.ScreenToWorldPoint(screenPoint);

Debug.LogFormat("mousePosition: {0} | zWorldDistanceFromCamera: {1} | worldPoint: {2}",
                Input.mousePosition,
                zWorldDistanceFromCamera,
                worldPoint.ToString("F3"));

(如果这不起作用,您是否可以更新您的问题或回复此帖子并附上评论,其中的详细信息显示每一步记录的值?)

答案 2 :(得分:0)

由于使用默认相机返回正确的值,我只需添加另一个来检测鼠标位置,而不依赖于渲染纹理/四边形设置。

答案 3 :(得分:0)

我只是在努力解决这个问题,这个问题帮助我找到了答案,所以谢谢您发布它!

问题与z轴或如何调用Camera.ScreenToWorldPoint没有关系。问题在于您正在调用的相机正在渲染到RenderTexture,并且RT的尺寸与游戏窗口的尺寸不匹配。我无法在reference source中找到该方法的实现,但是它所做的一切取决于RenderTexture的分辨率。

要对此进行测试,请单击游戏窗口中的stats按钮以显示游戏窗口的屏幕尺寸。您获得的坐标将匹配该分辨率与RenderTexture分辨率之间的比率。

解决方案:

  1. 不要在针对渲染纹理的相机上调用此方法,要么针对屏幕(无),要么创建与所需相机位置匹配的子相机
  2. 将RT分辨率与屏幕匹配。显然,这可能会影响性能,或者如果屏幕尺寸发生更改,则会导致问题。
  3. 请勿使用Camera.ScreenToWorldPoint。根据使用情况,使用射线广播可能更简单或更可靠。