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 动态替换识别图的更多相关文章

  1. Unity3D 动态地创建识别图

    前面介绍了EasyAR的单图识别,它是提前在Unity设置好图片路径的,那么如果我们的图片是存储在服务器上的,那么我们肯定不能直接把服务的图片地址填上去了.这个时候我们可以动态地创建识别图.步骤如下: ...

  2. Unity3D 创建动态的立方体图系统

    Unity3D 创建动态的立方体图系统 这一篇主要是利用上一篇的Shader,通过脚本来完成一个动态的立方体图变化系统. 准备工作如下: 创建一个新的场景.一个球体.提供给场景一个平行光,准备2个立方 ...

  3. 开发增强现实(AR)教程——识别图的那些坑

    第一期:Vuforia识别图的那些坑 一.Vuforia的图片识别机制 大学时学习的是计算机科学的数字媒体方向,图像处理粗略接触过,对于Vuforia的图片识别机制,只能大概讲一下步骤和猜想,无法给出 ...

  4. 3D动态人脸识别技术分析——世纪晟人脸识别实现三维人脸建模

    - 目录 - 国内3D动态人脸识别现状概况 - 新形势下人脸识别技术发展潜力 - 基于深度学习的3D动态人脸识别技术分析 1. 非线性数据建模方法 2. 基于3D变形模型的人脸建模 - 案例结合——世 ...

  5. Java 程序动态替换 docx 模板中定制值的实现例子

    项目系统中打印功能,导出 word 文档功能是挺常用的,本文介绍自定文档模板,程序实现模板内容中值替代的功能. 模板文件 template.docx ​ 执行 main public static v ...

  6. vue项目中,无需打包而动态更改背景图以及标题

    1.背景 今天,项目经理对已完成的项目提出了一个需求,即项目的基础功能目前针对于各个基层法院都适用,而对于不同的法院,我们每次都需要前端研发来更改所属法院的法院名称以及背景图,这样对于演示者来说是非常 ...

  7. Vue实现长按图片识别图中二维码

    Vue实现长按图片识别图中二维码 思路:要想实现可以识别图片中的二维码,那必定是要将这张图进行上传操作,上传则需要file对象格式.不管是在H5还是APP中,展示的图片都是通过url的方式展示在img ...

  8. 利用POI 技术动态替换word模板内容

    项目中需要实现一个功能,动态替换给定模板里面的内容,生成word文档提供下载功能. 中间解决了问题有: 1.页眉的文档logo图片解决,刚开始的时候,HWPFDocument 对象无法读取图片对象(已 ...

  9. 【转载】利用Unity自带的合图切割功能将合图切割成子图

    虽然目前网上具有切割合图功能的工具不少,但大部分都是自动切割或者根据plist之类的合图文件切割的, 这种切割往往不可自己微调或者很难维调,导致效果不理想. 今天逛贴吧发现了一位网友写的切割合图插件很 ...

  10. 使用Unity创造动态的2D水体效果

    者:Alex Rose 在本篇教程中,我们将使用简单的物理机制模拟一个动态的2D水体.我们将使用一个线性渲染器.网格渲染器,触发器以及粒子的混合体来创造这一水体效果,最终得到可运用于你下款游戏的水纹和 ...

随机推荐

  1. LIS求解(包括优化)

    首先,让我来看看LIS问题 Description 一个数的序列 bi,当 b1 < b2 < ... < bS 的时候,我们称这个序列是上升的.对于给定的一个序列(a1,a2,.. ...

  2. 真正“搞”懂HTTP协议09之这个饼干不能吃

    我们在之前的文章中介绍HTTP特性的时候聊过,HTTP是无状态的,每次聊起HTTP特性的时候,我都会回忆一下从前辉煌的日子,也就是互联网变革的初期,那时候其实HTTP不需要有状态,就是个浏览页面,没有 ...

  3. 用Java写一个分布式缓存——缓存管理

    前言 之前也用过一些缓存中间件,框架,也想着自己是不是也能用Java写一个出来,于是就有了这个想法,打算在写的过程中同步进行总结 源码:weloe/Java-Distributed-Cache (gi ...

  4. 2023 年该学点什么技术?「GitHub 热点速览 v.23.03」

    春节期间,小鱼干读了一篇万字回顾数据库行业的文章,在文字缝隙里我看见了两个词:AI+ 和数据两个词(当然数据是废话,毕竟是一个数据库的回顾文).在 GitHub 上热点趋势上,可见到 AI+ 的身影, ...

  5. 【分析笔记】全志 i2c-sunxi.c 控制器驱动分析

    分析平台:全志 A64 内核版本:Linux 4.9 数据手册:Allwinner_A64_User_Manual_V1.1.pdf (whycan.com) 驱动框架 I2C 设备驱动 作为方案应用 ...

  6. avalonia自定义弹窗

    对于使用avalonia的时候某些功能需要到一些提示,比如异常或者成功都需要对用户进行提示,所以需要单独实现弹窗功能,并且可以自定义内部组件,这一期将手动实现一个简单的小弹窗,并且很容易自定义 创建项 ...

  7. JSP第十一次作业

    1.第十二周上机作业(邮件功能)的控制层代码改用为servlet实现.2.学习通发布了考试,截止到本周六.  com.gd.dao  BaseDao 1 package com.gd.dao; 2 3 ...

  8. windows环境下部署一个Jenkins工程

    首先要安装配置好Jenkins环境变量,具体操作可参考其他文章 确保Jenkins可以正常运行之后开始进行项目的部署 首页点击新建,进行新建一个工程 进入项目添加界面,填入项目名称并选择构建一个自由风 ...

  9. Python实现随机森林RF并对比自变量的重要性

      本文介绍在Python环境中,实现随机森林(Random Forest,RF)回归与各自变量重要性分析与排序的过程.   其中,关于基于MATLAB实现同样过程的代码与实战,大家可以点击查看MAT ...

  10. .net core 上传文件到本地服务器

    1.本文是上传文件到本地服务器,主要以作者做的业务上传apk为例子,下面直接上代码 [HttpGet, HttpPost, HttpOptions] [Consumes("applicati ...