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. 01-Tcl基本知识

    1 Tcl基本知识 1.1 Tcl是什么? Tcl全称是Tool Command Language,是一种基于字符串的命令语言. Tcl是一种解释性语言,类似于其他脚本语言一样,直接对每条语句顺次解释 ...

  2. three.js实现分模块添加梦幻bloom辉光光晕方案--详细注释版本~~方案三版本~~

    先上图对比方案1-2-3不同点,本文是方案3 方案1(旋转场景情况下发光体不应该遮住另一个,但是遮住了) 方案2(层次正常,发光正常) 方案3(层次正常,发光正常,但是转动场景时候部分辉光会被遮挡,但 ...

  3. ng-alain创建组件添加路由导航菜单项基础步骤详解

    首先呢~ 我们要在需要创建模块的路径例如AAA目录下,在终端打开(就是和在shell窗口打开一样的) 然后 ng g ng-alain:module XXXmodule 好了,创建了一个模块 接下来会 ...

  4. Java 进阶P-6.4+P-6.5

    狐狸和兔子 狐狸和兔子都有年龄 当年龄到了一定的上限就会自然死亡 狐狸可以随即决定在周围的兔子中吃一个 狐狸和兔子可以随即决定生一个小的,放在旁边的空的格子里 如果不吃也不生,狐狸和兔子可以随机决定走 ...

  5. 静态static关机子修饰成员方法-静态static的内存图

    静态static关机子修饰成员方法 静态方法 当 static 修饰成员方法时,该方法称为类方法 .静态方法在声明中有 static ,建议使用类名来调用,而不需要 创建类的对象.调用方式非常简单. ...

  6. Windows 映射网络驱动器及删除-此网格连接不存在

    将共享目录,映射到本地磁盘,可以方便快速访问 添加 点击[此电脑]菜单栏中,选择[计算机]->[映射网格驱动器]-> 文件夹中输入 共享目录地址,如下图 删除 右击,网格映射盘,右击[断开 ...

  7. magic-api数据库存储方案

    建表语句 drop table if exists magic_api_file; CREATE TABLE `magic_api_file` ( `id` int(11) NOT NULL AUTO ...

  8. P30_全局配置 - window - 下拉刷新

    window 全局开启下拉刷新功能 概念:下拉刷新是移动端的专有名词,指的是通过手指在屏幕上的下拉滑动操作,从而重新加载页面数据的行为. 设置步骤:app.json -> window -> ...

  9. 剑指 Offer 34. 二叉树中和为某一值的路径(java解题)

    目录 1. 题目 2. 解题思路 3. 数据类型功能函数总结 4. java代码 1. 题目 给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总 ...

  10. WinUI 剪裁发布中的一个小坑

    WinUI 3 (以下简称 WinUI)框架发布后的二进制文件过大的问题存在了很长时间,我在这篇文章中有过详细的讨论,好在 Windows App SDK v1.2 就已经支持剪裁发布,但是我却一直没 ...