射线检测地表高度和世界坐标和屏幕坐标间的转换

来源:互联网 发布:实体渠道 数据分析 编辑:程序博客网 时间:2024/05/29 13:23

上文中介绍了基地范围显示办法。但是它是在投影在地面的,离这儿太远的话肯定看不到,我们需要个UI图标显示该位置。企鹅的坦克大战里的图是这样的

有个小旗子显示,这种图标做法类似血条,做法也很简单。主要涉及到世界坐标和屏幕坐标的转换

 

上文Projector从上往下投影,y轴的高低要求并不需要很精确。但是这个UI图标的显示就不是了。

服务器传过来的一个二维坐标,在客户端没有地形文件的情况下,怎么根据这个二维坐标在地形上查找对应的y轴高度?

可以用射线从上往下做射线碰撞,碰到的点就是地面的高度

 

①得到位置的世界坐标

若服务器发来的二维坐标是(a.b) 。地形上y轴代表高度,取一个一定高于地表的y值,从上往下发射线。

假设发射线的点为Vector3 pos = new Vector3(a,100,b)

Ray ray=new Ray(pos,Vector3.down);  //Vector3.down代表方向向下

RaycastHit hitInfo;     //声明要输出的碰撞点
int avalayer = LayerMask.NameToLayer("Terrain");  //根据地表名Terrain得到它的Layer层数

 if (Physics.Raycast(tRay, out hitInfo, 1000, 1 << avalayer)) 
        {
            pos = new Vector3(hitInfo.point.x, hitInfo.point.y + 5, hitInfo.point.z);  //得到碰撞点hitInfo.point 。并且设置UI贴图世界位置为该点以上5米
        }

 

在Update里更新UI位置

因为主角移动,摄像机也是跟着动的,所以虽然基地的位置固定但是相对于屏幕的位置也是需要不断变化的

 

void Update () 
  {

    Vector3 vecScr = Cam.intance.WorldToScreenPoint(vecworld);
        bool bShow = vecScr.z > float.Epsilon;   //是否显示
        if (!bShow)
        {
            sprite.gameObject.SetActive(false);
            return;
        }

  sprite.gameObject.SetActive(true);
        vecScr.z = 10;
        Vector3 screenPoint = vecScr;
        int mHalfWidth = Screen.width / 2;
        int mHalfHeight = Screen.height / 2;

        screenPoint.x -= mHalfWidth;
        screenPoint.y -= mHalfHeight;
        float adjustment = mUIRoot.pixelSizeAdjustment;
        screenPoint.x *= adjustment;
        screenPoint.y *= adjustment;
        sprite.depth = (int)vecScr.z * 10;
        screenPoint.z = 0;

        spritetran.transform.localPosition = screenPoint;
        screenPoint.y = screenPoint.y + 20;

 

 

好了,主要是射线碰撞得到地面高度和世界坐标和屏幕坐标的转换

 

 

 

 

0 0
原创粉丝点击