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); } } }