Vuforia开发高阶二-虚拟按钮(第一部分)

第一部分:  

Vuforia的所有功能中,虚拟按钮是唯一一个交互的功能,而且这个功能相当精彩,使用它可以开发很多有趣的应用。  

使用虚拟按钮demo,会有两个疑问:  
1、 按钮位置怎么确定的?  
2、 按钮怎么检测到的?  

首先给大家介绍按钮位置的确定。  
有两种方式:  
1、 自己通过公式计算。  
对于这种方式,只用做研究使用。实际开发过程中,不需要这么复杂。但是计算方法还是贴出来,以供参考。  
群里看到很多人在问虚拟按钮实例中的按钮坐标是怎么计算出来的,今天就给大家讲讲计算原理!  
问题:虚拟按钮这个位置坐标怎么确定的?  
 
见上图,原点在左上角,竖直方向为Y轴,水平方向是X轴,且是(1500,1050)像素。按钮的尺寸是(200,75)。  
下表中原始像素坐标分别为按钮矩形框中左上角和右下角的坐标值。  
右边一列是经过尺寸转换之后图片标志的坐标值。那么它是经过怎样的变换得来的呢??  
下面这幅图展示了该SDK3D坐标系。而上表右边的数据就是讲原始坐标系转化成3D坐标系得出的值。大家可以看到3D坐标系的原点在Image的中心,因此不难解释上表中会出现负值。  
下面给大家列出相应的计算公式。  
 
计算比较简单,用相似比就可以了,不过大家注意单位的转换。  
 
利用相似关系:  
90/750 =(123.5-X)/123.5  
利用这个公式计算出X108.68  
同理,可以计算出Y值,再判断正负,所以得出坐标值(-108.68-53.52  

2、 SDK自动计算。  
这里使用unity3d开发。  

复制代码
private Vector2 top;
 private Vector2 bottom;
  
    #region UNITY_MONOBEHAVIOUR_METHODS
  
    void Start()
    {
        // Register with the virtual buttons TrackableBehaviour
        VirtualButtonBehaviour[] vbs = GetComponentsInChildren<VirtualButtonBehaviour>();
        for (int i = 0; i < vbs.Length; ++i)
        {
            vbs.RegisterEventHandler(this);
   vbs.CalculateButtonArea(out top,out bottom);
   Debug.Log(vbs.VirtualButton.Name+"---->"+top.x+":"+top.y+"----->"+bottom.x+":"+bottom.y);
        }
  
        // Get handle to the teapot object
        mTeapot = transform.FindChild("teapot").gameObject;
  
        // The list of active materials
        mActiveMaterials = new List<Material>();
    }

计算结果:  
 
分别对应以下几个Virtual Button  
 

其实,在实际项目中,不需要计算按钮位置,直接使用Virtual Buttonprefab即可。  
unity3d平台下,主要涉及到一个类和一个接口:  
VirtualButtonEventHandler IVirtualButtonEventHandler 。这里是我自定义的一个类,但是必须要实现这个接口。  
其中这个接口包含两个方法:  
public   void  OnButtonPressed(VirtualButtonAbstractBehaviour vb)  
public   void  OnButtonReleased(VirtualButtonAbstractBehaviour vb)  
跟普通按钮一样,点击和释放的两个功能。  
 
这段代码大概的执行流程如下:  
1、 实现接口,重载接口方法  
2、 查找所有的 VirtualButtonBehaviour 组件,可以将其理解为一个 Button,然后每个button需要注册事件,  
3、 根据不同的button名称处理不同的事件  
其实程序执行就这三步。  

复制代码
public class VirtualButtonEventHandler : MonoBehaviour, 
                                        IVirtualButtonEventHandler 
{ 
   #region PUBLIC_MEMBER_VARIABLES 
  
   /// <summary> 
   /// The materials that will be set for the teapot model 
   /// </summary> 
   public Material[] m_TeapotMaterials; 
  
   #endregion // PUBLIC_MEMBER_VARIABLES 
  
  
  
   #region PRIVATE_MEMBER_VARIABLES 
     
   private GameObject mTeapot; 
   private List<Material> mActiveMaterials; 
  
   #endregion // PRIVATE_MEMBER_VARIABLES 
  
  
  
   #region UNITY_MONOBEHAVIOUR_METHODS 
  
   void Start() 
   { 
       // Register with the virtual buttons TrackableBehaviour 
       VirtualButtonBehaviour[] vbs = GetComponentsInChildren<VirtualButtonBehaviour>(); 
       for (int i = 0; i < vbs.Length; ++i) 
       { 
           vbs.RegisterEventHandler(this); 
       } 
  
       // Get handle to the teapot object 
       mTeapot = transform.FindChild("teapot").gameObject; 
  
       // The list of active materials 
       mActiveMaterials = new List<Material>(); 
   } 
  
   #endregion // UNITY_MONOBEHAVIOUR_METHODS 
  
  
  
   #region PUBLIC_METHODS 
     
   /// <summary> 
   /// Called when the virtual button has just been pressed: 
   /// </summary> 
   public void OnButtonPressed(VirtualButtonAbstractBehaviour vb) 
   { 
       Debug.Log("OnButtonPressed::" + vb.VirtualButtonName); 
  
       if (!IsValid()) 
       { 
           return; 
       } 
  
       // Add the material corresponding to this virtual button 
       // to the active material list: 
       switch (vb.VirtualButtonName) 
       { 
           case "red": 
               mActiveMaterials.Add(m_TeapotMaterials[0]); 
               break; 
  
           case "blue": 
               mActiveMaterials.Add(m_TeapotMaterials[1]); 
               break; 
  
           case "yellow": 
               mActiveMaterials.Add(m_TeapotMaterials[2]); 
               break; 
  
           case "green": 
               mActiveMaterials.Add(m_TeapotMaterials[3]); 
               break; 
       } 
  
       // Apply the new material: 
       if (mActiveMaterials.Count > 0) 
           mTeapot.GetComponent<Renderer>().material = mActiveMaterials[mActiveMaterials.Count - 1]; 
   } 
  
  
   /// <summary> 
   /// Called when the virtual button has just been released: 
   /// </summary> 
   public void OnButtonReleased(VirtualButtonAbstractBehaviour vb) 
   { 
       if (!IsValid()) 
       { 
           return; 
       } 
  
       // Remove the material corresponding to this virtual button 
       // from the active material list: 
       switch (vb.VirtualButtonName) 
       { 
           case "red": 
               mActiveMaterials.Remove(m_TeapotMaterials[0]); 
               break; 
  
           case "blue": 
               mActiveMaterials.Remove(m_TeapotMaterials[1]); 
               break; 
  
           case "yellow": 
               mActiveMaterials.Remove(m_TeapotMaterials[2]); 
               break; 
  
           case "green": 
               mActiveMaterials.Remove(m_TeapotMaterials[3]); 
               break; 
       } 
  
       // Apply the next active material, or apply the default material: 
       if (mActiveMaterials.Count > 0) 
           mTeapot.GetComponent<Renderer>().material = mActiveMaterials[mActiveMaterials.Count - 1]; 
       else
           mTeapot.GetComponent<Renderer>().material = m_TeapotMaterials[4]; 
   } 
  
  
   private bool IsValid() 
   { 
       // Check the materials and teapot have been set: 
       return  m_TeapotMaterials != null && 
               m_TeapotMaterials.Length == 5 && 
               mTeapot != null; 
   } 
  
   #endregion // PUBLIC_METHODS 
}

 
但是在这三步之前,还有一个工作必须要完成,就是在场景中配置虚拟按钮(VB)。  
Unity3D中,VirtualButton组件也是作为一个Prefab存在,只需要将其拖拽到对应的ImageTarget下,作为其子类,然后在scene中手动设置其位置和大小即可。  
 
 
其次需要对起进行行为设定,主要是 VirtualButtonBehaviour 这个脚本。  
 
主要有两个属性,一个 name,一个Sensitivity 设置。  
Name对应脚本中事件触发的判断,敏感度设置有三个选项,分别是低中高,越高越容易被识别,我一般设置我High  

然后在  

复制代码
public void OnButtonPressed(VirtualButtonAbstractBehaviour vb)方法体中加一句判断就好:
           case "test":// 该名称是由前面设置的
               mActiveMaterials.Remove(m_TeapotMaterials[3]);
               break;
  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值