归海一啸
管理员
管理员
  • 社区居民
  • 最爱沙发
  • 忠实会员
  • 喜欢达人
  • 原创写手
阅读:7875回复:23

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

楼主#
更多 发布于:2015-06-25 22:38
第一部分:

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

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

首先给大家介绍按钮位置的确定。
有两种方式:
1、自己通过公式计算。
对于这种方式,只用做研究使用。实际开发过程中,不需要这么复杂。但是计算方法还是贴出来,以供参考。
群里看到很多人在问虚拟按钮实例中的按钮坐标是怎么计算出来的,今天就给大家讲讲计算原理!
问题:虚拟按钮这个位置坐标怎么确定的?

图片:图片1.png


见上图,原点在左上角,竖直方向为Y轴,水平方向是X轴,且是(1500,1050)像素。按钮的尺寸是(200,75)。
下表中原始像素坐标分别为按钮矩形框中左上角和右下角的坐标值。
右边一列是经过尺寸转换之后图片标志的坐标值。那么它是经过怎样的变换得来的呢??
下面这幅图展示了该SDK3D坐标系。而上表右边的数据就是讲原始坐标系转化成3D坐标系得出的值。大家可以看到3D坐标系的原点在Image的中心,因此不难解释上表中会出现负值。
下面给大家列出相应的计算公式。

图片:图片2.jpg


计算比较简单,用相似比就可以了,不过大家注意单位的转换。

图片:图片3.png


利用相似关系:
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>();
    }

计算结果:

图片:图片4.png


分别对应以下几个Virtual Button

图片:图片5.png



其实,在实际项目中,不需要计算按钮位置,直接使用Virtual Buttonprefab即可。
unity3d平台下,主要涉及到一个类和一个接口:
VirtualButtonEventHandlerIVirtualButtonEventHandler。这里是我自定义的一个类,但是必须要实现这个接口。
其中这个接口包含两个方法:
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中手动设置其位置和大小即可。

图片:图片6.png


图片:图片7.png


其次需要对起进行行为设定,主要是VirtualButtonBehaviour这个脚本。

图片:图片8.png


主要有两个属性,一个name,一个Sensitivity 设置。
Name对应脚本中事件触发的判断,敏感度设置有三个选项,分别是低中高,越高越容易被识别,我一般设置我High

然后在
public void OnButtonPressed(VirtualButtonAbstractBehaviour vb)方法体中加一句判断就好:
           case "test":// 该名称是由前面设置的
               mActiveMaterials.Remove(m_TeapotMaterials[3]);
               break;

最新喜欢:

MelodyMelody dayelongshedayelo... 少年天蝎少年天蝎
AR学院(www.arvrschool.com),从这里感触未来!

欢迎分享

buptidsuper
骑士
骑士
  • UID33
  • 粉丝0
  • 关注0
  • 发帖数13
  • 社区居民
沙发#
发布于:2015-09-06 16:16
楼主用unity进行sdk计算虚拟按钮位置的方法真棒!!!
Ps:我记得还有一步,完成以上步骤之后,还需要在xml文件中写入对应virtual button的属性参数
tyf0321
新手
新手
  • UID575
  • 粉丝1
  • 关注0
  • 发帖数10
板凳#
发布于:2015-12-03 21:35
您这些代码放在那里说一下行吗,。,,,初学者真是不能理解
归海一啸
管理员
管理员
  • 社区居民
  • 最爱沙发
  • 忠实会员
  • 喜欢达人
  • 原创写手
地板#
发布于:2015-12-03 21:37
tyf0321:您这些代码放在那里说一下行吗,。,,,初学者真是不能理解回到原帖
好的,那建议你看一下视频教程吧~http://www.arvrschool.com/index.php?c=thread&fid=36
应该有所帮助。如果还有问题,欢迎交流~
AR学院(www.arvrschool.com),从这里感触未来!
tyf0321
新手
新手
  • UID575
  • 粉丝1
  • 关注0
  • 发帖数10
4楼#
发布于:2015-12-03 21:58
归海一啸:好的,那建议你看一下视频教程吧~http://www.arvrschool.com/index.php?c=thread&fid=36
应该有所帮助。如果还有问题,欢迎交流~
回到原帖
谢谢~
langzi001_ar
圣骑士
圣骑士
  • UID91
  • 粉丝4
  • 关注4
  • 发帖数64
5楼#
发布于:2015-12-11 16:52
       // 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];

这个不是很理解  不明白具体的意思(看不懂注释)
ljp2009
新手
新手
  • UID253
  • 粉丝0
  • 关注0
  • 发帖数9
6楼#
发布于:2015-12-15 22:33
楼主你好,我通过unity3d Unity 5.0.0f4 (32-bit)版本导入其他官方demo可以,但是这个虚拟按钮导入出错,是因为unity3d版本的原因还是什么原因呢?
楼主你好,我通过unity3d Unity 5.0.0f4 (32-bit)版本导入其他官方demo可以,但是这个虚拟按钮导入出错,是因为unity3d版本的原因还是什么原因呢?
出错信息是:Failed to import package with error: Couldn't decompress package


还有就是64位的软件运行不了官方的案例是吗?这是为什么呢?谢谢您的回答。
归海一啸
管理员
管理员
  • 社区居民
  • 最爱沙发
  • 忠实会员
  • 喜欢达人
  • 原创写手
7楼#
发布于:2015-12-15 22:44
ljp2009:楼主你好,我通过unity3d Unity 5.0.0f4 (32-bit)版本导入其他官方demo可以,但是这个虚拟按钮导入出错,是因为unity3d版本的原因还是什么原因呢?
出错信息是:Failed to import packag...
回到原帖
不是,你的安装包是不是没下载完整。
AR学院(www.arvrschool.com),从这里感触未来!
ljp2009
新手
新手
  • UID253
  • 粉丝0
  • 关注0
  • 发帖数9
8楼#
发布于:2015-12-15 22:49
呃 也可能是,我再下载一个试试,谢谢大师。
还有就是64位的unity3d软件是不是运行不了啊?我现在是32位软件能运行64位的运行不了,求真相。
归海一啸
管理员
管理员
  • 社区居民
  • 最爱沙发
  • 忠实会员
  • 喜欢达人
  • 原创写手
9楼#
发布于:2015-12-15 23:13
ljp2009:呃 也可能是,我再下载一个试试,谢谢大师。
还有就是64位的unity3d软件是不是运行不了啊?我现在是32位软件能运行64位的运行不了,求真相。
回到原帖
确实64位不好使,你就用32位好了
AR学院(www.arvrschool.com),从这里感触未来!
ljp2009
新手
新手
  • UID253
  • 粉丝0
  • 关注0
  • 发帖数9
10楼#
发布于:2015-12-16 21:00
归海一啸:不是,你的安装包是不是没下载完整。回到原帖
归海大师,我又在此论坛重新下载了一遍官方的demo,用unity3d 5.0  和unity3d 5.2 都加载VirtualButtons-5-0-5.unitypackage 一遍还是出错,错误信息还是:Failed to import package with error: Couldn't decompress package
绝对不是中文路径,真是不知道是怎么回事了,求帮助!谢谢
归海一啸
管理员
管理员
  • 社区居民
  • 最爱沙发
  • 忠实会员
  • 喜欢达人
  • 原创写手
11楼#
发布于:2015-12-16 22:14
ljp2009:归海大师,我又在此论坛重新下载了一遍官方的demo,用unity3d 5.0  和unity3d 5.2 都加载VirtualButtons-5-0-5.unitypackage 一遍还是出错,错误信息还是:Failed to import...回到原帖
你这个问题一般有两个原因:
1、中文路径
2、包没有下载完整
你说没有中文路径,那就是你得包没有下载完整,你看看
AR学院(www.arvrschool.com),从这里感触未来!
ljp2009
新手
新手
  • UID253
  • 粉丝0
  • 关注0
  • 发帖数9
12楼#
发布于:2015-12-16 23:31
恩是 我确定没有中文路径 下载文件的时候都下载了好几遍了 也不知道怎么算没下载完整,总是不成功。麻烦能给我发一个VirtualButtons-5-0-6.unitypackage 的文件吗?或者给我一个链接。实在是没办法了,哎。谢谢了。
归海一啸
管理员
管理员
  • 社区居民
  • 最爱沙发
  • 忠实会员
  • 喜欢达人
  • 原创写手
13楼#
发布于:2015-12-17 00:12
ljp2009:恩是 我确定没有中文路径 下载文件的时候都下载了好几遍了 也不知道怎么算没下载完整,总是不成功。麻烦能给我发一个VirtualButtons-5-0-6.unitypackage 的文件吗?或者给我一个链接。实在是没办法了,哎。谢谢了。回到原帖
你加入咱们QQ群,吼一声就行,AR/VR学院技术交流群 129340649
AR学院(www.arvrschool.com),从这里感触未来!
ljp2009
新手
新手
  • UID253
  • 粉丝0
  • 关注0
  • 发帖数9
14楼#
发布于:2015-12-17 13:03
归海一啸:你加入咱们QQ群,吼一声就行,AR/VR学院技术交流群 129340649回到原帖
恩恩好的 谢谢,已经搞定了 终于下载全了资源
上一页
游客

返回顶部