Unity平台 + Vuforia SDK实现的AR程序开发

  • 模型的三大操作(平移 旋转 缩放)代码
    • 一.平移
    • 二.旋转缩放
    • 三.操作代码解析
  • 模型的选定(射线法)
    • 食用方法
  • 自发光组件
    • 食用方法
  • VirtualButton虚拟按钮
    • 关于UI的Canvas使用方法请自行搜索
    • 关于按钮OnPress变色(红色)OnRelease蓝色
    • VB按钮的控制脚本构建
  • 代码终结篇总结

作者写在前面的话:
接触了1个多月的Vuforia以及AR知识,感觉可能了解为什么15-17爆发后,就很少有连续不断更新的教程了,一个原因是风头过了,大批开发者离开这个领域,理由很简单,没啥东西了,AR就这点东西对普通开发者来说,三维跟踪注册,触屏交互。再深究下去,没有利润养不起自己养不起开发人员。所以现在存活的AR技术提供商,只有面向工业医疗制造业航天航空等狗大户才能继续活下去。
但是可以预见的是,AR即是未来。
只是需要突破。交互,光学显示,虚实融合
***最后,顶,点赞,评论,收藏三连!如果觉得有用的话!是对作者最大的鼓励
***最后,顶,点赞,评论,收藏三连!如果觉得有用的话!是对作者最大的鼓励
***最后,顶,点赞,评论,收藏三连!如果觉得有用的话!是对作者最大的鼓励

在《【Vuforia AR Unity 2018.3.12f1】MikuAR安卓程序开发实践(二)MMD篇_2019.4.23》中已经放出了项目源码,也给出了详细的操作的步骤。
本篇主要针对解析的是对于按钮及其他控制的代码详情。下面开始干货时间。

模型的三大操作(平移 旋转 缩放)代码

所有的物体操作代码,都是放在该物体GameObject上新建的Script脚本中,一般来说,直接写在void Update()函数中。

一.平移

网上的教程关于平移很多,只不过,emmm写的不是很清楚,比如背景环境没写明白,也没写清楚逻辑,实验了很多次伸手党,结果经过很多次很麻烦的测试,还是不行。hhhh还是得自己来一步一步解析

平移参考资源网址:
1.Unity官网Manual
2. jswm20150115博客
3.qq_30454411博客

由2.3博客中不免发现,核心是transform.Translate()函数,emmm直接去1.Unity官网查询这个函数了。

欸!官网给出了实例,超级棒!
好了具体的实践和分析过程我就不列举出来,直接给成功的代码和注释。【伸手党最爱】

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Translate : MonoBehaviour //Script脚本名
{float speed = 0.2f;float Y, X;//设置X,Y轴中间变量可不设// Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){if (Input.touchCount > 0) //如果检测到有至少一个触屏点{//Touch touch = Input.GetTouch(0);//赋值第一个触碰点for (int i = 0; i < Input.touchCount; ++i)//所有触碰点移动均进行平移操作{if (Input.GetTouch(i).phase == TouchPhase.Began)//触碰点状态为 刚触碰{//计算物体XY位移量=屏幕位移*放缩倍数,手指位移时间小于1s缩,大于1放大,speed为固缩X = Input.GetTouch(i).deltaPosition.x * Time.deltaTime * speed;Y = Input.GetTouch(i).deltaPosition.y * Time.deltaTime * speed;transform.Translate(X, Y, 0, Space.World);//这个语句是核心,其他都是判断及参量构建}}}}
}

食用方法: 在需要平移的物体上挂载/新建 C# Script脚本 Component

核心语句: transform.Translate(X, Y, 0, Space.World);
关于这里的X,Y。我实验得出的结果是,这个Translate是屏幕平面的X,Y轴,对应Sence中的X,Z轴。emmm不妨大碍。就是有点拧巴。

二.旋转缩放

旋转缩放参考资源网址:
简书:U3D界金城武
拿来即可用,这是我查找到的最棒的代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class RotateScale : MonoBehaviour //新建的脚本名
{private Touch oldTouch1;  //上次触摸点1(手指1)  private Touch oldTouch2;  //上次触摸点2(手指2)  void Start(){}void Update(){//没有触摸  if (Input.touchCount <= 0){return;}//单点触摸, 水平上下旋转  if (1 == Input.touchCount){Touch touch = Input.GetTouch(0);Vector2 deltaPos = touch.deltaPosition;transform.Rotate(Vector3.down * deltaPos.x, Space.World);transform.Rotate(Vector3.right * deltaPos.y, Space.World);}//多点触摸, 放大缩小  Touch newTouch1 = Input.GetTouch(0);Touch newTouch2 = Input.GetTouch(1);//第2点刚开始接触屏幕, 只记录,不做处理  if (newTouch2.phase == TouchPhase.Began){oldTouch2 = newTouch2;oldTouch1 = newTouch1;return;}//计算老的两点距离和新的两点间距离,变大要放大模型,变小要缩放模型  float oldDistance = Vector2.Distance(oldTouch1.position, oldTouch2.position);float newDistance = Vector2.Distance(newTouch1.position, newTouch2.position);//两个距离之差,为正表示放大手势, 为负表示缩小手势  float offset = newDistance - oldDistance;//放大系数float scaleFactor = offset / 100f;Vector3 localScale = transform.localScale;Vector3 scale = new Vector3(localScale.x + scaleFactor,localScale.y + scaleFactor,localScale.z + scaleFactor);//最小缩放到 0.1 倍  if (scale.x > 0.1f && scale.y > 0.1f && scale.z > 0.1f){transform.localScale = scale;}//记住最新的触摸点,下次使用  oldTouch1 = newTouch1;oldTouch2 = newTouch2;}
}

三.操作代码解析

  1. 平移的话,没有太多要点,因为太简单了。主要就是先判断是否触摸,然后再读取一共有多少个触摸点,然后再进行循环,以保证所有的触摸点的移动都被读取,而不是只读第一个//Touch touch = Input.GetTouch(0);所以要进入for循环。Input.GetTouch()可以在Unity官网手册查询具体的,而且Unity的手册都带有实例,而且对于新手来说有可能超级有用,很基础很实用的例子。如果你找不到老师,请去官网翻手册,这是最高效的信息来源。
  2. 关于旋转和缩放,旋转核心语句是transform.Rotate(),需要确定旋转方向,即是Vector3.down及Vector3.right两个参量,这个两个参量是可以更改的,看你自己的需求,需要注意的是旋转是单点操作和平移是冲突的。缩放的话核心语句是transform.localScale属性的赋值,思路是先确定两触摸点距离变化是增大还是减小,然后获取模型原各轴缩放尺寸,将增大/减少值更新至原缩放尺寸,然后再赋值回到模型各轴缩放尺寸属性。
  3. 我个人将模型的旋转平移写在一个脚本里,将平移单独写在一个脚本里,通过VirtualButton来控制脚本的enable属性,从而实现对模型的平移与旋转可在一个程序中运行。如下图,是平移VB按钮的控制脚本,在OnPress的时候将Miku模型上的RotateScale脚本关闭,并同时将Translate脚本启用。

模型的选定(射线法)

射线法参考资源网址:
用编程改变世界 博客_他也是转载的
feng 文章 腾讯游戏学园

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class RayControl : MonoBehaviour
{public Camera camera;public HighlightableObject ho;float speed = 0.5f;float Y, X;GameObject gameObj = null;RaycastHit hitInfo;//下面注释的是从某博客上获取的一段代码,主要是用于其他GameObject静态调用获取物体的公共方法/*public static GameObject getCollisionObc(Camera camera, Vector3 touchPos){UnityEngine.Ray ray = camera.ScreenPointToRay(touchPos);//从摄像机发出到点击坐标的射线RaycastHit hitInfo;GameObject gameObj = null;if (Physics.Raycast(ray, out hitInfo)){//获取碰撞的物体Debug.DrawLine(ray.origin, hitInfo.point, Color.red);//划出射线,只有在scene视图中才能看到gameObj = hitInfo.collider.gameObject;return gameObj;}else{return null;}}*/// Start is called before the first frame updatevoid Start(){//ho = GetComponent<HighlightableObject>();ho.FlashingOn(Color.red, Color.blue, 1f); //此函数是自发光插件的函数,用于启动发光}// Update is called once per framevoid Update(){if (Input.touchCount > 0){//Move the cube if the screen has the finger moving.for (int i = 0; i < Input.touchCount; ++i){if (Input.GetTouch(i).phase == TouchPhase.Began){//Construct a ray from the current touch coordinatesUnityEngine.Ray ray = camera.ScreenPointToRay(Input.GetTouch(i).position);//camera变量是在Unity中拖动ARCamera赋值的,因为他是Public可以在Unity看到赋值框//Create a particle if hitif (Physics.Raycast(ray, out hitInfo)) //如果从摄像机发出的射线碰到物体返回hitInof变量{gameObj = hitInfo.collider.gameObject; //获取该物体X = Input.GetTouch(i).deltaPosition.x * Time.deltaTime * speed;Y = Input.GetTouch(i).deltaPosition.y * Time.deltaTime * speed;gameObj.transform.Translate(X, Y, 0, Space.World); //平移该物体ho.FlashingOff(); //关闭模型自发光}}}}}
}

食用方法

①这个脚本是 挂载/Add Component 在ARCamera上的
②需要被射线选中的对象必须加collider
③被射中的GameObject可以用"RaycastHit hitInfo"变量来调用。

自发光组件

模型自发光资源:
HighlightingSystem插件学习文档 博客 魔卡先生

食用方法

  1. Import HighlightingSystem.unitypackage。
    在MUKIARProgram\MyTestAR_SourceCode\Assets\ImportPackage路径下
    //插件导入时如若报错,将错误行代码注释掉即可

  2. 在ARCamera上挂载 Highlighting Effect 脚本,用于渲染外发光。不需要自己写搜索脚本名即可。

  3. 在需要外发光效果的物体上添加 Highlightable Object 脚本,用于外发光效果显示。

  4. 在需要外发光效果的物体上添加控制脚本,或者是在其他GameObject的脚本中获取该物体的HighlightableObject ho对象。我是在ARCamera中的射线法脚本中通过Public HighlightableObject直接拖拽Miku对象获取Miku的ho对象,从而控制Miku的自发光。

  5. 核心控制语句:
    //循环往复外发光开启(参数为:颜色1,颜色2,切换时间)
    m_ho.FlashingOn(Color.green, Color.blue, 1f);
    //关闭循环往复外发光
    m_ho.FlashingOff();
    //持续外发光开启(参数:颜色)
    m_ho.ConstantOn(Color.yellow);
    //关闭持续外发光
    m_ho.ConstantOff();

VirtualButton虚拟按钮

  • VirtualButton是依赖于ImageTarget生成的。
  • VirtualButton敏感度不是很有效,强烈不建议放置在识别图边缘区域,因为你会发现你无法控制按钮状态。
  • 并且通过实验可以得知VirtualButton不能放置ImageTarget外
  • VirtualButton最好放置在ImageTarget中心区域,那里手指触碰实际效果最好。
  • 单独的VirtualButton,可以使用,但无法在屏幕上看到,需要与Canvas搭配使用,Canvas是用来显示VirtualButton区域。VirtualButton本身是一个碰撞域,无形无色。

关于UI的Canvas使用方法请自行搜索

并不是特别困难
Canvas用途:显示文字

关于按钮OnPress变色(红色)OnRelease蓝色

1.创建Canvas层,并创建下属材质子层
2.在材质子层创建下属文字层
3.在VB虚拟按钮中控制Canvas中对应的材质子层的材质

  • Canvas层【下属3个按钮的材质子层】
  • 材质子层【用于显示在用户屏幕上颜色】【材质在Materials文件夹中】
  • 文字层

VB按钮的控制脚本构建

所有的按钮都是一个模子。三个状态OnPress,OnRelease,OnHold
废话不多说,直接上代码。下面是Dance VB的控制脚本

  • Dance VB
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using Vuforia;public class DanceControl : MonoBehaviour, IVirtualButtonEventHandler
{//按钮三个执行状态public UnityEvent onPress;public UnityEvent onHold;public UnityEvent onRelease;//获取VB对象public VirtualButtonBehaviour btn;//被摁下标识bool isPressed;Animation animOpenCurtain;public void OnButtonPressed(VirtualButtonBehaviour vb){//if (onPress != null)onPress.Invoke();isPressed = true;//获取MIku模型,并进行播放animOpenCurtain = GameObject.Find("MikuV4X").GetComponent<Animation>();animOpenCurtain.Play();}public void OnButtonReleased(VirtualButtonBehaviour vb){//if (onRelease != null)onRelease.Invoke();isPressed = false;//throw new System.NotImplementedException();}// Start is called before the first frame updatevoid Start(){//注册该按钮在全局事件监听btn = GetComponent<VirtualButtonBehaviour>();btn.RegisterEventHandler(this);//animator = GetComponent<Animator>();}// Update is called once per framevoid Update(){if (isPressed)onHold.Invoke();}
}
  • 平移,旋转缩放两个控制脚本【只是类名不同】
    代码里其实没有什么。只是在Unity面板里进行了简单可视化编程
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using Vuforia;public class TranslateControl : MonoBehaviour, IVirtualButtonEventHandler
{public UnityEvent onPress;public UnityEvent onHold;public UnityEvent onRelease;public VirtualButtonBehaviour btn;bool isPressed;public void OnButtonPressed(VirtualButtonBehaviour vb){//if (onPress != null)onPress.Invoke();isPressed = true;}public void OnButtonReleased(VirtualButtonBehaviour vb){//if (onRelease != null)onRelease.Invoke();isPressed = false;//throw new System.NotImplementedException();}// Start is called before the first frame updatevoid Start(){btn = GetComponent<VirtualButtonBehaviour>();btn.RegisterEventHandler(this);//animator = GetComponent<Animator>();}// Update is called once per framevoid Update(){if (isPressed)onHold.Invoke();}
}


代码终结篇总结

设计思路很简单,在实践的第一篇中有图做详细介绍。简单的来说就是,通过按钮控制模型的动画,模型的平移旋转缩放,还有通过射线法操控模型,更改模型属性等。
这个实践完全是自己盲人摸象一样的趟过来的,如果说反思的话,就是几个方面

  • 信息收集来讲:
    背景信息还不错,脑子里有相当的脉络。
    实操的信息来说,走了很多弯路,挨了很多毒打。尤其是AndroidSDK的变迁;其次就是平移这个最简单的坎儿,因为网上的代码有些缺乏背景信息,从电脑上制作打包APK再测试就很麻烦,在懒惰了很多次后,才选择看官网手册。不得不说,Unity真的很良心。果然高质量信息搜寻,还是优先官网吧。
  • 关于Unity的动画系统:
    因为这个程序走的是MMD插件,所以不太需要去了解Animator和Animation两个动画系统,比较遗憾,但是从VMD插入到MMD程序生成的过程来看,真的有点很复杂的样子,对于我这样不被要求很深入的了解的人来说,MMD真的是帮了很大的忙!不过好像Animator和Animation的控制函数不是很多,还是比较简单的样子,复杂的地方应该是在于制作动作和模型的方面。
  • Unity开发Android程序测试很麻烦浪费了很多时间。希望以后能找到更好的解决方法。
  • VB也测试了很多时间,因为它总是处于被摁下的状态,后来在一个博客里无意间看到,最好扔到中间,试了试,大致解决了这个问题,这也凸显出AR交互的一个十分不太方便的地方。
  • 关于移动端和PC端的区别,只是外界信息源获取的函数不同罢了
    GetTouch or Mouse
  • 做东西一定先写构思图,因为……很可能坐着做着就忘记要干嘛了……hhhhh,其次便是耐心,总会有解决办法,只是你没找到,一步一步去分解问题,一个一个解决,便会离最终目标越来越近。
  • 本项目在Github已开源。如果有优化的想法,且有时间,欢迎你的贡献。

【Vuforia AR Unity 2018.3.12f1】MikuAR安卓程序开发实践(三)代码终结篇_2019.4.24相关推荐

  1. 【Vuforia AR Unity 2018.3.12f1】MikuAR安卓程序开发实践(二)MMD篇_2019.4.23

    Unity平台 + Vuforia SDK实现的AR程序开发 !版权声明 项目源码 关于Github项目下载过慢的解决方法 关于Gitee下载报错的问题 一.解析 1 源码目录 2 Unity项目目录 ...

  2. android入门程序源代码,安卓程序开发入门

    您可能感兴趣的话题: 安卓程序开发入门 核心提示:本教程为大家介绍采用Eclipse软件来编写安卓Hello,World程序. 创建一个新项目是很简单的,只要你安装了Eclipse插件,并且你的Ecl ...

  3. 安卓程序开发需要学习哪些语言

    Android是以Linux为中心的手机操作平台,作为一款开放式的操作系统,跟着Android的快速发展,现在已允许开发者运用多种编程语言来开发Android应用程序,而不像曾经那样只能运用Java语 ...

  4. 安卓程序开发——创建安卓虚拟机

    创建虚拟机 安装好Eclipse+ADT,并设置好Android SDK路径后,点击图中按钮,或选择菜单中相应的选项,打开AVD Manager(安卓虚拟设备管理器). 点击New按钮 填写名称.内存 ...

  5. 简单好用的安卓程序开发平台E4A

    E4A为安卓程序中文开发平台,开放平台搭建过程简单,安卓程序编写简单快速! E4A发布版需要收费,免费版则是附带广告的.(对于不是用于商业软件来说,使用免费版是可以的) 转载于:https://www ...

  6. 干货 | 携程酒店安卓地图开发实践

    作者简介 亦枫,携程资深软件工程师,负责酒店业务 Android 客户端的相关研发工作. 当前大多数移动互联网 App 都会存在地图相关功能,尤其是 LBS(基于位置服务)相关的业务,依赖性更强,携程 ...

  7. 安卓TV开发(三) 移动智能设备之实现主流TV电视盒子焦点可控UI

    前言:移动智能设备的发展,推动了安卓另一个领域,包括智能电视和智能家居,以及可穿戴设备的大量使用,但是这些设备上的开发并不是和传统手机开发一样,特别是焦点控制和用户操作体验上有很大的区别,本系列博文主 ...

  8. vuforia ar unity 案例 从零开发 二 扫描图片展示模型

    首先打开vuforia官网 找到之前上传的扫描图 如没有点击add database上传  点击download 选择unityeditor   然后导入到unity里边 然后点击licenseman ...

  9. vuforia ar unity 案例从零制作 三 番外 假如想在一个程序扫描多个图片,出现不同模型

    如果我们一张图做一个程序 app显然不合理,至少我们得做一个类别的,一个系列的,多个图包含的 那么经过测试,实现其实很简单 我们选中iamgetarget 按下 ctrl+D 复制一份,吧他的data ...

最新文章

  1. 合并两个有序数组(重新开始)
  2. 安徽师范大学计算机专业导师,安徽师范大学数学计算机科学学院导师介绍:罗永龙...
  3. linux定时导出数据库,linux 下定时导出备份oracle数据库
  4. DllRegisterServer的调用失败
  5. 14K Star,「程序员做饭指南」冲上热榜
  6. 关于字符编码,你所需要知道的
  7. birt插件 web_Maven方式集成BIRT 4.6 Webviewer
  8. js读取cookie,js添加cookie,js删除cookie
  9. 手把手教你强化学习 (五) 为什么需要值迭代和策略迭代
  10. JSON 数据类型转换工具
  11. Scala安装教程(windows和linux)
  12. jquery动画顺序执行_深入理解jquery自定义动画animate()
  13. Windows版bitcoin客户端编译
  14. D3 天眼查 股权结构图
  15. 从苹果2015年春季发布会看移动互联网的发展
  16. Hive输出文件的间隔符
  17. 判断文件或目录是否存在的几种方式
  18. Oracle:根据身份证号码查询年龄最大的人
  19. weex 使用指南和坑
  20. java面试app_java面试题库app

热门文章

  1. 全网首发AutoCAD 2008 完美64位简体中文版支持win7/win8(无局部英文)支持插件
  2. ComposeUI——日历控件(CalendarComponent)
  3. 从奥本海默的浮沉谈科学与政治的关系
  4. QGIS基础:创建矢量数据(栅格矢量化)
  5. [附源码]计算机毕业设计JAVA网上学车预约系统
  6. 虚拟机调用方法之ArtMethod
  7. SWFObject文件上传使用记录
  8. Teststand-控件
  9. SQL Server 数据库基本操作入门篇【2】
  10. 【Github】hexo结合Butterfly主题从零开始建github.io博客(待配置butterfly主题,暂停