美文网首页Unity技术分享Unity基础入门分享unity
[Unity] 投机处理3D转2D坐标不准的问题

[Unity] 投机处理3D转2D坐标不准的问题

作者: _Walker__ | 来源:发表于2017-09-11 18:30 被阅读201次
    指示屏幕外单位
      最近搞了个屏幕外重要单位指示的东西,效果见上图。开发过程中发现:当GameObject在Camera后面的时候,WorldToViewportPoint计算出来的坐标可能不准确。从表现上看,是错误的位置和正确的位置是关于屏幕中心对称的(对角线关系)。
      问了一些人,说这种情况要自己计算。苦想半天也不知道要怎么算(数学忘光有点伤)Orz...最后找了个取巧的办法。问题产生的情况是对象在相机后面,那么计算时把对象位置拉到相机前面应该就可以了吧?
      顺着这个思路,我把GameObject的坐标投影到相机的近裁切面上,然后用投影点的坐标进行计算 —— 得到了想要的结果~

    下面记录几个要点备忘:

    1. 用Plane表示近裁切面
    Plane nearPlane = new Plane();
    Vector3 forward = camTrans.forward;
    Vector3 center = camTrans.position + (forward * cam.nearClipPlane);
    nearPlane.SetNormalAndPosition(forward, center);
    
    1. 用NearPlane判断是否需要矫正坐标
      只有NearPlane后面的对象需要矫正
    // NearPlane前面的一个点坐标
    Vector3 forwordPoint = _nearPlane.Center + _nearPlane.Forward;
    if (_nearPlane.NearPlane.SameSide(forwordPoint, target.position))
    {
      // 矫正
    }
    else
    {
      // 不矫正
    }
    
    1. 获得目标延相机方向在NearPlane上的投影坐标(矫正后的坐标)
      Unity提供了Vector3.ProjectOnPlane做Vector3向平面的投影,但在这里它不能用。从它两个形参就能看出了,它是做向量的投影,而不是点;它需要的投影平面仅用一个法向量表示,而我要的是一个过定点的平面。
      没有找到投影的API,最后采用了射线的方案。
    Ray projectRay = new Ray();
    projectRay.direction = forward;
    projectRay.origin = target.position;
    float dis;
    if (NearPlane.Raycast(_projectRay, out dis))
    {
        // 投影后的坐标!
        Vector3 projPoint = _projectRay.GetPoint(dis);
    }
    

    相关文章

      网友评论

        本文标题:[Unity] 投机处理3D转2D坐标不准的问题

        本文链接:https://www.haomeiwen.com/subject/mnefsxtx.html