涂涂乐中的扫描框

之前在试玩一些涂涂乐的应用,发现大多数AR扫描时,屏幕都会有一个扫描框。个人觉得这样的设计非常不错,只有当需要的识别图出现在扫描框内时才可以渲染出模型。
这两天抽出时间,做了一个简单的demo。

环境:
- unity5.2.2
- vuforia6.2.10


创建面片

在场景中新建面片Plane,调整面片的位置和大小与Imagetarget重合。

扫描框的四个屏幕坐标

首先在Canvas上创建一个Image作为扫描框,屏幕的分辨率是800*600,而Image的大小为400*300.单击canvas在右侧的Inspector,把Canvas——Render Mode设置为Screen Space—overlay。在Canvas Scaler的UI Scale Moder设置为Scale With Sceen Size。
这里写图片描述

扫描框的四个坐标,如下图所示:

这里写图片描述

那么由此得出

TopLeft_UI = new Vector2 ((Screen.width-400)*0.5f,(Screen.height-300)*0.5f+300f);
        BottomLeft_UI = new Vector2 ((Screen.width-400)*0.5f,(Screen.height-300)*0.5f);
        TopRight_UI = new Vector2 ((Screen.width-400)*0.5f+400f,(Screen.height-300)*0.5f+300f);
        BottomRight_UI = new Vector2 ((Screen.width-400)*0.5f+400f,(Screen.height-300)*0.5f);

计算面片上的四个点的坐标

在Plane新建四个空节点,位置调整到plane的四个顶点上。
这里写图片描述

在脚本上获取到这四个点的世界坐标

    public Transform TopLeft_PI;  //面片左上角坐标
    public Transform BottomLeft_PI;//面片左左角坐标
    public Transform TopRight_PI;//面片右上角坐标
    public Transform BottomRight_PI;//面片右下角坐标

在将这四个点的世界坐标转化成屏幕坐标

    void Update () {
        TopLeft_W_Sc = ToScreenPosition (TopLeft_PI.position);
        BottomLeft_W_Sc = ToScreenPosition (BottomLeft_PI.position);
        TopRight_W_Sc = ToScreenPosition (TopRight_PI.position);
        BottomRight_W_Sc = ToScreenPosition (BottomRight_PI.position);

    private Vector2 ToScreenPosition(Vector3 pointPos)
    {
        return Camera.main.WorldToScreenPoint (pointPos);
    }

最后只要比较plane的四个点的屏幕坐标是否在Image里就可以了。把Plane设置成ImageTarget的子节点下,运行时就可以看到效果了。
附上完整代码:

    private Vector2 TopLeft_UI;  //扫描框左上角坐标
    private Vector2 BottomLeft_UI;//扫描框左左角坐标
    private Vector2 TopRight_UI;//扫描框右上角坐标
    private Vector2 BottomRight_UI;//扫描框右下角坐标


    private Vector2 TopLeft_W_Sc;  //记录面片左上角的屏幕坐标
    private Vector2 BottomLeft_W_Sc;//记录面片左下角的屏幕坐标
    private Vector2 TopRight_W_Sc;//记录面片右上角的屏幕坐标
    private Vector2 BottomRight_W_Sc;//记录面片右下角的屏幕坐标

    public GameObject Plane;

    public Transform TopLeft_PI;  //面片左上角坐标
    public Transform BottomLeft_PI;//面片左左角坐标
    public Transform TopRight_PI;//面片右上角坐标
    public Transform BottomRight_PI;//面片右下角坐标

    public Material red;
    public Material green;

    // Use this for initialization
    void Start () 
    {
        TopLeft_UI = new Vector2 ((Screen.width-400)*0.5f,(Screen.height-300)*0.5f+300f);
        BottomLeft_UI = new Vector2 ((Screen.width-400)*0.5f,(Screen.height-300)*0.5f);
        TopRight_UI = new Vector2 ((Screen.width-400)*0.5f+400f,(Screen.height-300)*0.5f+300f);
        BottomRight_UI = new Vector2 ((Screen.width-400)*0.5f+400f,(Screen.height-300)*0.5f);

    }

    // Update is called once per frame
    void Update () {


        TopLeft_W_Sc = ToScreenPosition (TopLeft_PI.position);
        BottomLeft_W_Sc = ToScreenPosition (BottomLeft_PI.position);
        TopRight_W_Sc = ToScreenPosition (TopRight_PI.position);
        BottomRight_W_Sc = ToScreenPosition (BottomRight_PI.position);

        if (BeyondOut()) //是否超出扫描框的范围{
            Plane.GetComponent<MeshRenderer> ().material = green;
        } else {
            Plane.GetComponent<MeshRenderer> ().material = red;
        }

    }

    private Vector2 ToScreenPosition(Vector3 pointPos)
    {
        return Camera.main.WorldToScreenPoint (pointPos);
    }

    private bool BeyondOut()
    {
        return TopLeft_W_Sc.x > TopLeft_UI.x && TopLeft_W_Sc.y < TopLeft_UI.y && BottomLeft_W_Sc.x > BottomLeft_UI.x &&
        BottomLeft_W_Sc.y > BottomLeft_UI.y && TopRight_W_Sc.x < TopRight_UI.x && TopRight_W_Sc.y < TopRight_UI.y &&
        BottomRight_W_Sc.x < BottomRight_UI.x && BottomRight_W_Sc.y > BottomRight_UI.y ? true : false;
    }

在扫描框内:
这里写图片描述

没有完全在扫描框内:
这里写图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值