说明:
这篇文章的目的主要介绍如何在Vufoia移动端运行状态下动态添加资源(常见的类型如:添加模型、添加视频、添加透明视频等),在此之前需要了解的有:
须知:
- (1)这里的视频播放组件是基于Vufoia提供的视频预制体
- (2)文章中所涉及到的路径问题:
- 1:资源文件如果是预制在程序中的,路径可根据资源现有路径得到
- 2:资源文件如果是通过程序运行才下载得到的,路径必须为Application.persistentDataPath下,具体原因是因为移动端资源下载只能存放在该路径下,不易移动到其他路径下,其他常见路径 如:Application.streamingAssetsPath为只读路径,不能操作.
- (3)透明视频特意对Vufoia 进行的操作,并且Shader方面有特殊操作,需要自行解决,具体解决可查看相关资料文件
- (4)添加的模型是指进行了打包处理的资源文件,如果常见的预制体,完全不需要这么处理,只需要Resource.Load方式加载并实例化即可.
代码部分:
记住打包之后的模型:
/// <summary>
/// 加载普通模型
/// </summary>
/// <param name="ObjPath">资源所在路径</param>
/// <param name="TrackerName">资源实例化之后的位于Vufoia某一个Tracker的位置</param>
/// <param name="ObjName">资源实例化之后的名字</param>
/// <returns></returns>
static GameObject LoadModel(string ObjPath,string TrackerName,string ObjName)
{
FileStream AssetIO = new FileStream(ObjPath, FileMode.Open, FileAccess.ReadWrite); //创建文件流(对象现含有中文)
byte[] assetbytes = new byte[AssetIO.Length];
AssetIO.Read(assetbytes, 0, (int)AssetIO.Length);
AssetIO.Close();
Debug.Log(ObjPath);
AssetBundle asset = AssetBundle.CreateFromMemoryImmediate(assetbytes);//从内存中创建资源
if (asset ==null) {
return null;
}
AssetBundle LoadAssets = asset;//这样就能得到我们需要的资源包了
var InstObj = (GameObject)Instantiate(LoadAssets.LoadAllAssets<GameObject>()[0]);
asset.Unload(false);
InstObj.transform.SetParent(GameObject.Find(TrackerName).transform,false);
InstObj.name = ObjName;
return InstObj;
}
加载普通常见视频文件:
/// <param name="MoviePath">资源所在路径</param>
/// <param name="TrackerName">资源实例化之后的位于Vufoia某一个Tracker的位置</param>
/// <param name="MovieName">资源实例化之后的名字</param>
/// <returns></returns>
static GameObject LoadMovie(string MoviePath, string TrackerName,string MovieName)
{
var VideoPrefab = (GameObject)Instantiate(Resources.Load("XQResources/Video"));
VideoPrefab.transform.SetParent(GameObject.Find(TrackerName).transform,false);
VideoPrefab.name = MovieName;
VideoPrefab.GetComponentInChildren<VideoPlaybackBehaviour>().m_path = MoviePath;
VideoPrefab.GetComponentInChildren<VideoPlaybackBehaviour>().enabled = true;
return VideoPrefab;
}
加载透明视频文件:
static GameObject LoadTransparentMovie(string TransparentMoviePath, string TrackerName, string TransparentMovieName)
{
var VideoPrefab = (GameObject)Instantiate(Resources.Load("XQResources/TransparentVideo"));
VideoPrefab.transform.SetParent(GameObject.Find(TrackerName).transform, false);
VideoPrefab.name = TransparentMovieName;
VideoPrefab.tag = "TransparentMovie";
VideoPrefab.GetComponentInChildren<VideoPlaybackBehaviour>().m_path = TransparentMoviePath;
VideoPrefab.GetComponentInChildren<VideoPlaybackBehaviour>().enabled = true;
return VideoPrefab;
}
添加视频文件时需注意:
var VideoPrefab = (GameObject)Instantiate(Resources.Load("XQResources/TransparentVideo"));
这里添加的预制体是直接克隆Vufoia提供的视频文件进行的,如下所示:
两个预制体唯一的不同点就在于所使用的Shader文件有所不同,需要自行处理一下.
透明视频添加代码中的添加tag也是为了作出区分,便于在其他需要区分处理的地方处理:
VideoPrefab.tag = "TransparentMovie";
添加一个静态方法方便用于调用:
/// <param name="ObjPath">资源所在路径</param>
/// <param name="TrackerName">资源实例化之后的位于Vufoia某一个Tracker的位置</param>
/// <param name="Type">资源类型</param>
/// <param name="ObjName">资源实例化之后的名字</param>
/// <returns></returns>
public static GameObject LoadObject(string ObjPath,string TrackerName,string Type,string ObjName)
{
switch (Type)
{
case "Model":
return LoadModel(ObjPath, TrackerName,ObjName);
case "Movie":
return LoadMovie(ObjPath, TrackerName, ObjName);
case "TransparentMovie":
return LoadTransparentMovie(ObjPath, TrackerName, ObjName);
case "IMG":
return LoadIMG(ObjPath, TrackerName, ObjName);
default:
return null;
break;
}
}
完整代码如下所示:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Vuforia;
using System.IO;
/// <summary>
/// 动态添加AR相关物体或视频
/// </summary>
public class LoadARObject:MonoBehaviour
{
/// <param name="ObjPath">资源所在路径</param>
/// <param name="TrackerName">资源实例化之后的位于Vufoia某一个Tracker的位置</param>
/// <param name="Type">资源类型</param>
/// <param name="ObjName">资源实例化之后的名字</param>
/// <returns></returns>
public static GameObject LoadObject(string ObjPath,string TrackerName,string Type,string ObjName)
{
switch (Type)
{
case "Model":
return LoadModel(ObjPath, TrackerName,ObjName);
case "Movie":
return LoadMovie(ObjPath, TrackerName, ObjName);
case "TransparentMovie":
return LoadTransparentMovie(ObjPath, TrackerName, ObjName);
case "IMG":
return LoadIMG(ObjPath, TrackerName, ObjName);
default:
return null;
break;
}
}
/// <summary>
/// 加载普通模型
/// </summary>
/// <param name="ObjPath">资源所在路径</param>
/// <param name="TrackerName">资源实例化之后的位于Vufoia某一个Tracker的位置</param>
/// <param name="ObjName">资源实例化之后的名字</param>
/// <returns></returns>
static GameObject LoadModel(string ObjPath,string TrackerName,string ObjName)
{
FileStream AssetIO = new FileStream(ObjPath, FileMode.Open, FileAccess.ReadWrite); //创建文件流(对象现含有中文)
byte[] assetbytes = new byte[AssetIO.Length];
AssetIO.Read(assetbytes, 0, (int)AssetIO.Length);
AssetIO.Close();
Debug.Log(ObjPath);
AssetBundle asset = AssetBundle.CreateFromMemoryImmediate(assetbytes);//从内存中创建资源
if (asset ==null) {
return null;
}
AssetBundle LoadAssets = asset;//这样就能得到我们需要的资源包了
var InstObj = (GameObject)Instantiate(LoadAssets.LoadAllAssets<GameObject>()[0]);
asset.Unload(false);
InstObj.transform.SetParent(GameObject.Find(TrackerName).transform,false);
InstObj.name = ObjName;
return InstObj;
}
/// <param name="MoviePath">资源所在路径</param>
/// <param name="TrackerName">资源实例化之后的位于Vufoia某一个Tracker的位置</param>
/// <param name="MovieName">资源实例化之后的名字</param>
/// <returns></returns>
static GameObject LoadMovie(string MoviePath, string TrackerName,string MovieName)
{
var VideoPrefab = (GameObject)Instantiate(Resources.Load("XQResources/Video"));
VideoPrefab.transform.SetParent(GameObject.Find(TrackerName).transform,false);
VideoPrefab.name = MovieName;
VideoPrefab.GetComponentInChildren<VideoPlaybackBehaviour>().m_path = MoviePath;
VideoPrefab.GetComponentInChildren<VideoPlaybackBehaviour>().enabled = true;
return VideoPrefab;
}
static GameObject LoadTransparentMovie(string TransparentMoviePath, string TrackerName, string TransparentMovieName)
{
var VideoPrefab = (GameObject)Instantiate(Resources.Load("XQResources/TransparentVideo"));
VideoPrefab.transform.SetParent(GameObject.Find(TrackerName).transform, false);
VideoPrefab.name = TransparentMovieName;
VideoPrefab.tag = "TransparentMovie";
VideoPrefab.GetComponentInChildren<VideoPlaybackBehaviour>().m_path = TransparentMoviePath;
VideoPrefab.GetComponentInChildren<VideoPlaybackBehaviour>().enabled = true;
return VideoPrefab;
}
}