Unity Vuforia 动态替换识别图
1.在Unity里 Vuforia 用来做识别信息的是 StreamingAssets 下 Vuforia文件夹内的 Dat和XML 文件。
2.想要替换识别图需要在Vuforia官网里替换识别图 (这里替换的识别图名字要和之前的识别图名字一样),
替换完成后直接下载所有文件 选择Android文件 直接获取 Dat和XML文件,然后把这俩文件传至服务器
3.在打包之后,每次打开应用的时候做更新检查,如果有更新就去服务器下载这俩文件替换掉原来的文件(Android包 没法用IO读取
StreamingAssets下的文件, 直接用UnityWebReques 替换就行)
2.之前的理解有问题,其实不是替换原先的Dat和XML文件, 是重新下载新的Dat和XML 文件 通过代码的方式动态
加载识别图,达到替换的目的,默认的加载顺序是上传到Vuforia里的顺序
这是一个大概思路后续等我写完,会贴上代码
我是把这个代码放在ARCamera 上的, 打开应用下载完Dat和XML 以后,加载ARCamera 顺带着就初始化了识别图信息。目前使用下来没什么问题,就是注意它默认加载顺序(这个顺序是固定的)
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.UI;
using Vuforia;
using QFramework;
/// <summary>
/// 识别图管理器
/// </summary>
public class ImageTargetManager : MonoSingleton<ImageTargetManager>
{
//public Text logtest; //public Text errortext;
// public List<GameObject> listShowObj;
/// <summary>
/// 识别图加载完成
/// </summary>
public event Action<string[]> ImageTargerLoadedEvent; /// <summary>
/// 本地文件路径
/// </summary>
private string m_localFilePath;
/// <summary>
/// 是否加载过
/// </summary>
private bool m_isLoaded;
/// <summary>
/// 数据集
/// </summary>
private DataSet m_dataSet = null;
/// <summary>
/// 识别器
/// </summary>
private ObjectTracker m_tracker;
/// <summary>
/// 识别图集合对象
/// </summary>
private ImageTargetBehaviour[] m_imageTargetBehaviours; private void Start()
{
// Debug.Log(" Inited " + m_isLoaded);
m_isLoaded = false;
//TODO 识别图相关信息加载
//VuforiaBehaviour.Instance.RegisterVuforiaInitializedCallback(VuforiaInitedCallBack); try
{
VuforiaARController.Instance.RegisterVuforiaInitializedCallback(VuforiaInitedCallBack);
VuforiaARController.Instance.RegisterVuforiaStartedCallback(VuforiaStaredtCallBack);
}
catch (Exception e)
{ // errortext.text = e.Message;
}
}
/// <summary>
/// 高通初始化完毕回调
/// </summary>
void VuforiaInitedCallBack()
{
m_localFilePath = Application.persistentDataPath + "/StreamingAssets/Vuforia/" + AppConfigConst.IMAGE_TARGET_FILE_NAME + ".xml"; Debug.Log( " Inited@@@ "+m_localFilePath+" " +File.Exists(m_localFilePath));
//logtest.text = " Inited@@@ " + m_localFilePath + " " + File.Exists(m_localFilePath);
if (File.Exists(m_localFilePath))
{
//Load Local
StartCoroutine(LoadLocalFile());
}
else
{
//Load NetWork
//StartCoroutine(LoadNetworkFile());
}
} void VuforiaStaredtCallBack()
{
CameraDevice.Instance.SetFocusMode(CameraDevice.FocusMode.FOCUS_MODE_CONTINUOUSAUTO);
// errortext.text = CameraDevice.Instance.SetFocusMode(CameraDevice.FocusMode.FOCUS_MODE_CONTINUOUSAUTO).ToString(); //auto focus
} /// <summary>
/// 加载网络配置文件
/// </summary>
/// <returns></returns>
private IEnumerator LoadNetworkFile()
{
WWW wwwdat = new WWW(AppConfigConst.IMAGE_TARGET_FILE_PATH + AppConfigConst.IMAGE_TARGET_FILE_NAME + ".dat");
yield return wwwdat; Debug.Log(wwwdat.url);
WWW wwwxml = new WWW(AppConfigConst.IMAGE_TARGET_FILE_PATH + AppConfigConst.IMAGE_TARGET_FILE_NAME + ".xml");
yield return wwwxml; File.WriteAllBytes(Application.persistentDataPath + "/" + AppConfigConst.IMAGE_TARGET_FILE_NAME + ".dat", wwwdat.bytes);
File.WriteAllBytes(Application.persistentDataPath + "/" + AppConfigConst.IMAGE_TARGET_FILE_NAME + ".xml", wwwxml.bytes);
StartCoroutine(LoadLocalFile());
} /// <summary>
/// 加载本地配置文件
/// </summary>
/// <returns></returns>
IEnumerator LoadLocalFile()
{
bool isVuforiaEnabled = VuforiaRuntimeUtilities.IsVuforiaEnabled();
Debug.Log(isVuforiaEnabled);
// logtest.text = "isVuforiaEnabled " + isVuforiaEnabled + " m_isLoaded " + m_isLoaded;
if (isVuforiaEnabled && m_isLoaded == false)
{
if (m_dataSet == null)
{
m_tracker = TrackerManager.Instance.GetTracker<ObjectTracker>();
m_dataSet = m_tracker.CreateDataSet();
} Debug.Log("LoadData " + m_localFilePath);
// logtest.text = "LoadData " + m_localFilePath;
ObjectTracker objectTracker = TrackerManager.Instance.GetTracker<ObjectTracker>();
objectTracker.Stop();
if (m_dataSet.Load(m_localFilePath, VuforiaUnity.StorageType.STORAGE_ABSOLUTE))
{
Debug.Log("LoadData OVer " + m_localFilePath);
// logtest.text = "LoadData OVer " + m_localFilePath; m_isLoaded = true;
m_tracker.ActivateDataSet(m_dataSet);
// errortext.text = m_tracker.ActivateDataSet(m_dataSet).ToString(); objectTracker.Start();
UpdateImageTarget(); }
else
{
m_isLoaded = false;
}
}
WWW www = new WWW("file:///" + m_localFilePath);
yield return www;
} /// <summary>
/// 修改Imagetarget 的名称
/// </summary>
void UpdateImageTarget()
{
List<string> imagetargetNameList = new List<string>();
m_imageTargetBehaviours = FindObjectsOfType<ImageTargetBehaviour>();
// logtest.text = m_imageTargetBehaviours.Length.ToString();
for (int i = 0; i < m_imageTargetBehaviours.Length; i++)
{
ImageTargetBehaviour imageTargetBehaviour = m_imageTargetBehaviours[i];
// logtest.text = logtest.text+" "+ m_imageTargetBehaviours[i].name;
imageTargetBehaviour.name = "ImageTarget_" + imageTargetBehaviour.ImageTarget.Name; //imageTargetBehaviour.gameObject.AddComponent<DefaultTrackableEventHandler>(); //读取 DefaultTrackableEventHandler.lua
imageTargetBehaviour.gameObject.AddComponent<DefaultTrackableEventHandler>();
// imageTargetBehaviour.gameObject.AddComponent<LuaTrackableEventHandler>();
imageTargetBehaviour.gameObject.AddComponent<TurnOffBehaviour>();
imageTargetBehaviour.gameObject.AddComponent<VuforialFindImageAction>();
imagetargetNameList.Add(imageTargetBehaviour.name); //listShowObj[i].transform.parent = imageTargetBehaviour.transform;
//listShowObj[i].transform.localPosition = Vector3.zero;
VuforialFindImageAction imageaction = imageTargetBehaviour.gameObject.GetComponent<VuforialFindImageAction>();
GameObject obj = new GameObject("Cube");
obj.transform.parent = imageaction.transform;
obj.transform.localEulerAngles = new Vector3(90, 0, 0);
obj.transform.localPosition = Vector3.zero; imageaction.num = i;
imageaction.targetObj = obj.transform;
imageaction.pointObj = 0; } OnImageTargerLoadedEvent(imagetargetNameList.ToArray());
} /// <summary>
/// 获取所有的识别图对象
/// </summary>
/// <returns></returns>
public ImageTargetBehaviour[] GetImageTargetBehaviours()
{
return m_imageTargetBehaviours;
} protected virtual void OnImageTargerLoadedEvent(string[] obj)
{
var handler = ImageTargerLoadedEvent;
if (handler != null)
{
handler(obj);
}
}
}
Unity Vuforia 动态替换识别图的更多相关文章
- Unity3D 动态地创建识别图
前面介绍了EasyAR的单图识别,它是提前在Unity设置好图片路径的,那么如果我们的图片是存储在服务器上的,那么我们肯定不能直接把服务的图片地址填上去了.这个时候我们可以动态地创建识别图.步骤如下: ...
- Unity3D 创建动态的立方体图系统
Unity3D 创建动态的立方体图系统 这一篇主要是利用上一篇的Shader,通过脚本来完成一个动态的立方体图变化系统. 准备工作如下: 创建一个新的场景.一个球体.提供给场景一个平行光,准备2个立方 ...
- 开发增强现实(AR)教程——识别图的那些坑
第一期:Vuforia识别图的那些坑 一.Vuforia的图片识别机制 大学时学习的是计算机科学的数字媒体方向,图像处理粗略接触过,对于Vuforia的图片识别机制,只能大概讲一下步骤和猜想,无法给出 ...
- 3D动态人脸识别技术分析——世纪晟人脸识别实现三维人脸建模
- 目录 - 国内3D动态人脸识别现状概况 - 新形势下人脸识别技术发展潜力 - 基于深度学习的3D动态人脸识别技术分析 1. 非线性数据建模方法 2. 基于3D变形模型的人脸建模 - 案例结合——世 ...
- Java 程序动态替换 docx 模板中定制值的实现例子
项目系统中打印功能,导出 word 文档功能是挺常用的,本文介绍自定文档模板,程序实现模板内容中值替代的功能. 模板文件 template.docx 执行 main public static v ...
- vue项目中,无需打包而动态更改背景图以及标题
1.背景 今天,项目经理对已完成的项目提出了一个需求,即项目的基础功能目前针对于各个基层法院都适用,而对于不同的法院,我们每次都需要前端研发来更改所属法院的法院名称以及背景图,这样对于演示者来说是非常 ...
- Vue实现长按图片识别图中二维码
Vue实现长按图片识别图中二维码 思路:要想实现可以识别图片中的二维码,那必定是要将这张图进行上传操作,上传则需要file对象格式.不管是在H5还是APP中,展示的图片都是通过url的方式展示在img ...
- 利用POI 技术动态替换word模板内容
项目中需要实现一个功能,动态替换给定模板里面的内容,生成word文档提供下载功能. 中间解决了问题有: 1.页眉的文档logo图片解决,刚开始的时候,HWPFDocument 对象无法读取图片对象(已 ...
- 【转载】利用Unity自带的合图切割功能将合图切割成子图
虽然目前网上具有切割合图功能的工具不少,但大部分都是自动切割或者根据plist之类的合图文件切割的, 这种切割往往不可自己微调或者很难维调,导致效果不理想. 今天逛贴吧发现了一位网友写的切割合图插件很 ...
- 使用Unity创造动态的2D水体效果
者:Alex Rose 在本篇教程中,我们将使用简单的物理机制模拟一个动态的2D水体.我们将使用一个线性渲染器.网格渲染器,触发器以及粒子的混合体来创造这一水体效果,最终得到可运用于你下款游戏的水纹和 ...
随机推荐
- LIS求解(包括优化)
首先,让我来看看LIS问题 Description 一个数的序列 bi,当 b1 < b2 < ... < bS 的时候,我们称这个序列是上升的.对于给定的一个序列(a1,a2,.. ...
- 真正“搞”懂HTTP协议09之这个饼干不能吃
我们在之前的文章中介绍HTTP特性的时候聊过,HTTP是无状态的,每次聊起HTTP特性的时候,我都会回忆一下从前辉煌的日子,也就是互联网变革的初期,那时候其实HTTP不需要有状态,就是个浏览页面,没有 ...
- 用Java写一个分布式缓存——缓存管理
前言 之前也用过一些缓存中间件,框架,也想着自己是不是也能用Java写一个出来,于是就有了这个想法,打算在写的过程中同步进行总结 源码:weloe/Java-Distributed-Cache (gi ...
- 2023 年该学点什么技术?「GitHub 热点速览 v.23.03」
春节期间,小鱼干读了一篇万字回顾数据库行业的文章,在文字缝隙里我看见了两个词:AI+ 和数据两个词(当然数据是废话,毕竟是一个数据库的回顾文).在 GitHub 上热点趋势上,可见到 AI+ 的身影, ...
- 【分析笔记】全志 i2c-sunxi.c 控制器驱动分析
分析平台:全志 A64 内核版本:Linux 4.9 数据手册:Allwinner_A64_User_Manual_V1.1.pdf (whycan.com) 驱动框架 I2C 设备驱动 作为方案应用 ...
- avalonia自定义弹窗
对于使用avalonia的时候某些功能需要到一些提示,比如异常或者成功都需要对用户进行提示,所以需要单独实现弹窗功能,并且可以自定义内部组件,这一期将手动实现一个简单的小弹窗,并且很容易自定义 创建项 ...
- JSP第十一次作业
1.第十二周上机作业(邮件功能)的控制层代码改用为servlet实现.2.学习通发布了考试,截止到本周六. com.gd.dao BaseDao 1 package com.gd.dao; 2 3 ...
- windows环境下部署一个Jenkins工程
首先要安装配置好Jenkins环境变量,具体操作可参考其他文章 确保Jenkins可以正常运行之后开始进行项目的部署 首页点击新建,进行新建一个工程 进入项目添加界面,填入项目名称并选择构建一个自由风 ...
- Python实现随机森林RF并对比自变量的重要性
本文介绍在Python环境中,实现随机森林(Random Forest,RF)回归与各自变量重要性分析与排序的过程. 其中,关于基于MATLAB实现同样过程的代码与实战,大家可以点击查看MAT ...
- .net core 上传文件到本地服务器
1.本文是上传文件到本地服务器,主要以作者做的业务上传apk为例子,下面直接上代码 [HttpGet, HttpPost, HttpOptions] [Consumes("applicati ...