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

5 篇文章 0 订阅
4 篇文章 0 订阅

作者写在前面的话:
接触了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 update
    void Start()
    {
        
    }
    
    // Update is called once per frame
    void 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 update
    void Start()
    {
        //ho = GetComponent<HighlightableObject>();
        ho.FlashingOn(Color.red, Color.blue, 1f); //此函数是自发光插件的函数,用于启动发光
    }

    // Update is called once per frame
    void 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 coordinates
                    UnityEngine.Ray ray = camera.ScreenPointToRay(Input.GetTouch(i).position);
                    //camera变量是在Unity中拖动ARCamera赋值的,因为他是Public可以在Unity看到赋值框

                     //Create a particle if hit
                    if (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 脚本,用于渲染外发光。不需要自己写搜索脚本名即可。
    挂载Effect脚本

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

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

  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用途:显示文字
Canvas

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

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

  • Canvas层【下属3个按钮的材质子层】
    Canvas层
  • 材质子层【用于显示在用户屏幕上颜色】【材质在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 update
    void Start()
    {
    	//注册该按钮在全局事件监听
        btn = GetComponent<VirtualButtonBehaviour>();
        btn.RegisterEventHandler(this);
        //animator = GetComponent<Animator>();
    }

    // Update is called once per frame
    void 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 update
    void Start()
    {
        btn = GetComponent<VirtualButtonBehaviour>();
        btn.RegisterEventHandler(this);
        //animator = GetComponent<Animator>();
    }

    // Update is called once per frame
    void Update()
    {
        if (isPressed)
            onHold.Invoke();
    }
}

Rotate面板
Translate面板

代码终结篇总结

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

  • 信息收集来讲:
    背景信息还不错,脑子里有相当的脉络。
    实操的信息来说,走了很多弯路,挨了很多毒打。尤其是AndroidSDK的变迁;其次就是平移这个最简单的坎儿,因为网上的代码有些缺乏背景信息,从电脑上制作打包APK再测试就很麻烦,在懒惰了很多次后,才选择看官网手册。不得不说,Unity真的很良心。果然高质量信息搜寻,还是优先官网吧。
  • 关于Unity的动画系统:
    因为这个程序走的是MMD插件,所以不太需要去了解Animator和Animation两个动画系统,比较遗憾,但是从VMD插入到MMD程序生成的过程来看,真的有点很复杂的样子,对于我这样不被要求很深入的了解的人来说,MMD真的是帮了很大的忙!不过好像Animator和Animation的控制函数不是很多,还是比较简单的样子,复杂的地方应该是在于制作动作和模型的方面。
  • Unity开发Android程序测试很麻烦浪费了很多时间。希望以后能找到更好的解决方法。
  • VB也测试了很多时间,因为它总是处于被摁下的状态,后来在一个博客里无意间看到,最好扔到中间,试了试,大致解决了这个问题,这也凸显出AR交互的一个十分不太方便的地方。
  • 关于移动端和PC端的区别,只是外界信息源获取的函数不同罢了
    GetTouch or Mouse
  • 做东西一定先写构思图,因为……很可能坐着做着就忘记要干嘛了……hhhhh,其次便是耐心,总会有解决办法,只是你没找到,一步一步去分解问题,一个一个解决,便会离最终目标越来越近。
  • 本项目在Github已开源。如果有优化的想法,且有时间,欢迎你的贡献。
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
### 回答1: Vuforia是一款用于增强现实(AR)应用开发的软件。Hololens是一款由微软推出的AR眼镜。Unity是一种用于多平台游戏和应用程序开发的跨平台游戏引擎。Unity 2020.3 LTS是Unity的一个稳定版本。 在使用Unity 2020.3 LTS时,我们可以利用Vuforia插件和Hololens设备来开发AR应用程序。Unity提供了Vuforia Hololens 1和2的示例项目,这些示例项目提供了一个基础模板,可以帮助开发者更好地理解AR应用程序的开发和实现。 在这些示例项目中,开发者可以学习如何使用Vuforia插件来识别现实世界中的图像和对象,并将其与虚拟对象进行交互和融合。通过使用Hololens设备,开发者可以在现实世界的环境中将虚拟对象投射到真实世界中,实现更加真实的AR体验。 在开发AR应用程序时,开发者应该注意选择合适的技术和工具,例如Vuforia和Hololens设备,并熟悉其使用。Unity 2020.3 LTS提供了一个稳定的开发环境,方便开发者进行AR应用程序的开发和实现。 ### 回答2: Vuforia Hololens是一款在Hololens平台上运行的增强现实开发工具,其可以增强Hololens用户的体验,使用户可以通过头戴式显示器看到虚拟对象与显示屏的混合视觉场景。同时,Vuforia Hololens还提供了在Unity 2020.3 LTS中的样例项目,该项目可以帮助开发者更快速、更有效地开发Hololens应用程序。 Vuforia Hololens在Hololens平台上提供了强大的AR功能,例如图像识别、目标跟踪、手势识别等。这些功能可以使Hololens应用程序更加互动和富有创意,利用这些功能,设计师可以创造出更多具有体验感和趣味性的虚拟体验。 在Unity 2020.3 LTS中,Vuforia Hololens还提供了样例项目,该项目展示了如何使用Vuforia Hololens进行AR开发。开发者可以使用该项目作为模板,快速上手Hololens的AR开发。该项目提供了详细的文档,包含如何安装和使用Vuforia Hololens、如何在Hololens平台上进行AR开发等。 总之,Vuforia Hololens作为一款强大的Hololens增强现实开发工具,为Hololens应用程序的开发者提供了很多便利。与此同时,Vuforia Hololens在Unity 2020.3 LTS中提供的样例项目可以使开发者更加高效地进行Hololens应用程序的开发。 ### 回答3: Vuforia 是一个由 PTC 公司开发的增强现实引擎,可以与 Hololens 1 和 2 无缝集成,而 Unity 2020.3 LTS 是 Unity 的一个长期支持版本。在 Unity 中,我们可以使用 Vuforia 引擎来创建增强现实应用程序,可以通过扫描图像或实际物体来在 Hololens 中呈现虚拟对象。该引擎提供了自动识别、跟踪和显示虚拟对象的功能,开发人员可以依靠 Vuforia 引擎将虚拟内容融合到现实世界中。 在使用 Unity 2020.3 LTS 版本开发 Vuforia Hololens 1 和 2 应用程序时,可以使用 Vuforia 官方提供的 Unity 范例。这些范例提供了一些基本的场景和功能,如在 Hololens 上显示虚拟物体、通过手势控制虚拟物体等。开发人员可以使用这些范例作为起点,在其基础上进一步开发自己的应用程序,实现更丰富的功能。 总之,利用 VuforiaUnity 构建 Hololens 1 和 2 应用程序可以为用户提供全新的增强现实体验,这将有助于拓展 Hololens 在教育、培训、医疗等领域的应用。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值