1.使用AssetBundle压缩资源上传到服务器
使用AssetBundle压缩资源上传到服务器
由于测试需要,可以把需要的数据模型等,直接放到服务器上。本人直接将需要下载的视频资源放到七流云空间。
编写脚本,不需要挂在任何物体上,Unity3D会检测到打包脚本,打包方法如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor; //导入系统相关类
public class BUNAssets : MonoBehaviour {
[@MenuItem("Test/Build Asset Bundles")] //添加菜单栏"Test”以及子菜 单"Build Asset Bundles”
//声明BuildAssetBundles方法
// 打包位置到指定文件夹下
static void BuildAssetBundles()
{
BuildPipeline.BuildAssetBundles(Application.dataPath + "/Assetbundle", BuildAssetBundleOptions.UncompressedAssetBundle,BuildTarget.iOS);
}
}
2.个人最近研究的是EasyAR的官方SDK ,其中主要脚本官方已经给出,个人开发可以根据官方给的脚本进行操作实施,脚本编程如下
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using System.IO;
using System.Net;
using UnityEngine.UI;
using System.Threading;
//using UnityEngine.UI;
namespace EasyAR
{
public class EasyImageTargetBehaviour : ImageTargetBehaviour
{
bool isDone;
// Image image;
Text text;
float localprogress ;
HttpDownLoad http;
public string BundleURL;
public string AssetName ; // 预控件名称
// strat 方法
protected override void Awake()
{
BundleURL = Application.dataPath + "/Assetbundle/workroom.mp4";
text = GameObject.Find ("Canvas/Text").gameObject.GetComponent<Text> (); //进度条文字 拿到项目上悬挂的脚本找到Text控件
base.Awake();
TargetFound += OnTargetFound;
TargetLost += OnTargetLost;
TargetLoad += OnTargetLoad;
TargetUnload += OnTargetUnload;
}
protected void Update()
{
// if (System.IO.File.Exists (Application.dataPath + "/Assetbundle/workroom.mp4") == true) {
// return;
// }
text.text = "资源加载中" + (http.progress * 100).ToString ("0.00") + "%";
if(http.progress == 1)
{
if (System.IO.File.Exists (Application.dataPath + "/Assetbundle/1164.mov") == true) {
Debug.Log ("Update 中 拿到下载完毕----");
isDone = false;
Destroy(GameObject.Find("Canvas/Text")); //销毁资源
http.Close ();
}
}
}
void OnTargetFound(TargetAbstractBehaviour behaviour)
{
Debug.Log("OnTargetFound: " + Target.Id +Target.Name);
if (System.IO.File.Exists (Application.dataPath +"/Assetbundle/1164.mov") == false) {
// StartCoroutine (progress1.DownloadVideo (@"http://ot24avzj3.bkt.clouddn.com/1164.mov", Application.dataPath +"/Assetbundle/1164.mov"));
// 判断异步对象并且异步对象没有加载完毕,显示进度
http = new HttpDownLoad();
http.DownLoad(@"http://ot24avzj3.bkt.clouddn.com/1164.mov", Application.dataPath +"/Assetbundle/1164.mov", LoadLevel);
// Down_List ();
return;
}
// 该处需根据个人需要加载个人所需要的资源
// AssetBundle modelBundle = AssetBundle.LoadFromFile (BundleURL); //根据文本路径找到打包的数据
// GameObject model = modelBundle.LoadAsset (AssetName) as GameObject;//根据预控件的名字加载模型
// if (model != null) {
// Instantiate (model); //实例化模型
// }
// model.transform.position = new Vector3 (-10f, 0f, 0f); // 设置位置
// modelBundle.Unload (false);//卸载资源
}
void LoadLevel()
{
isDone = true;
}
void OnTargetLost(TargetAbstractBehaviour behaviour)
{
Debug.Log("Lost: " + Target.Id);
if (Target.Name == "koala") {
text.text = "";
http.Close ();
}
}
void OnTargetLoad(ImageTargetBaseBehaviour behaviour, ImageTrackerBaseBehaviour tracker, bool status)
{
Debug.Log("Load target (" + status + "): " + Target.Id + " (" + Target.Name + ") " + " -> " + tracker);
}
void OnTargetUnload(ImageTargetBaseBehaviour behaviour, ImageTrackerBaseBehaviour tracker, bool status)
{
Debug.Log("Unload target (" + status + "): " + Target.Id + " (" + Target.Name + ") " + " -> " + tracker);
}
}
3.下载脚本,编程如下。
涉及的知识点有
1. 线程的使用 Thread
2. 流文件的操作 FileStream
3. 网络下载 HttpWebRequest(同理也可以使用官方在推崇的WWW方式,个人使用过之后觉得大多已被封装,可扩展操作性空间较小)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net;
using System.IO;
using System;
using System.Threading;
public class HttpDownLoad{
//下载进度
public float progress{get; private set;} //C#私有属性,set 前面加private 告诉编译器属性是只读的,外部不能给属性赋值,只能读取其值
//涉及子线程要注意,Unity关闭的时候子线程不会关闭,所以要有一个标识
private bool isStop;
//子线程负责下载,否则会阻塞主线程,Unity界面会卡主
public Thread thread;
//表示下载是否完成
public bool isDone{get; private set;}
const int oneReadLen = 16384; // 一次读取长度 16384 = 16*kb
const int ReadWriteTimeOut = 2 * 1000; // 超时等待时间
const int TimeOutWait = 5 * 1000; // 超时等待时间
const int MaxTryTime = 3;
/// <summary>
/// 下载方法(断点续传)
/// </summary>
/// <param name="url">URL下载地址</param>
/// <param name="savePath">Save path保存路径</param>
/// <param name="callBack">Call back回调函数</param>
public void DownLoad(string downUrl, string savePath, Action callBack)
{
if (System.IO.File.Exists (savePath) == true ) { //如果本地文件存在储存路劲则
return;
}
isStop = false;
//开启子线程下载,使用匿名方法
thread = new Thread(delegate() {
//打开上次下载的文件
long startPos = 0;
string tempFile = savePath+".temp";
FileStream fs = null; // 文件
//使用流操作文件
if (File.Exists(tempFile))
{
fs = File.OpenWrite(tempFile);
startPos = fs.Length;
}
else
{
string direName = Path.GetDirectoryName(tempFile); //返回指定路径字符串的目录信息
if (!Directory.Exists(direName)) Directory.CreateDirectory(direName); //在direName目录下创建目录
fs = new FileStream(tempFile, FileMode.Create);//创建流文件
}
//获取文件现在的长度
long fileLength = fs.Length;
//获取下载文件的总长度
long totalLength = GetLength(downUrl);
//如果没下载完
if(fileLength < totalLength)
{
//断点续传核心,设置本地文件流的起始位置
fs.Seek(fileLength, SeekOrigin.Begin);
//创建网络请求
HttpWebRequest request = HttpWebRequest.Create(downUrl) as HttpWebRequest;
//断点续传核心,设置远程访问文件流的起始位置
request.AddRange((int)fileLength);
Stream stream = request.GetResponse().GetResponseStream();
byte[] buffer = new byte[1024];
//使用流读取内容到buffer中
//注意方法返回值代表读取的实际长度,并不是buffer有多大,stream就会读进去多少
int length = stream.Read(buffer, 0, buffer.Length);
while(length > 0)
{
//如果Unity客户端关闭,停止下载
if(isStop) break;
//将内容再写入本地文件中
fs.Write(buffer, 0, length);
//计算进度
fileLength += length;
// 判断是否下载完成
if (fileLength == totalLength)
{
fs.Flush();// 清除该流的所有缓冲区,使得所有缓冲的数据都被写入到基础设备
fs.Close();// 关闭流
fs = null;
if (File.Exists(savePath)) File.Delete(savePath);
File.Move(tempFile, savePath); // 下载完成将temp文件,改成正式文件
}
progress = (float)fileLength / (float)totalLength;
UnityEngine.Debug.Log(progress);
//类似尾递归
length = stream.Read(buffer, 0, buffer.Length); // 返回读入缓冲区的最大字节
}
stream.Close(); // 关闭链接
stream.Dispose(); // 这个链接不需要了,可以释放资源
}
else
{
progress = 1;
fs.Flush();
fs.Close();
fs = null;
if (File.Exists(savePath)) File.Delete(savePath); //如果文件里存在了,就删了
File.Move(tempFile, savePath);
}
fs.Close();
fs.Dispose();
//如果下载完毕,执行回调
if(progress == 1)
{
isDone = true;
if(callBack != null) callBack();
}
});
//开启子线程
thread.IsBackground = true;
thread.Start();
}
/// <summary>
/// 获取下载文件的大小
/// </summary>
/// <returns>The GetLength.</returns>
/// <param name="url">URL.</param>
public static long GetLength(string url)
{
HttpWebRequest request = null;
WebResponse respone = null;
long length = 0;
try
{
request = WebRequest.Create(url) as HttpWebRequest;
// request.Timeout = TimeOutWait;
// request.ReadWriteTimeout = ReadWriteTimeOut;
//向服务器请求,获得服务器回应数据流
respone = request.GetResponse();
length = respone.ContentLength;
}
catch (WebException e)
{
throw e;
}
finally
{
if (respone != null) respone.Close();
if (request != null) request.Abort();
}
return length;
}
public void Close()
{
isStop = true;
}
}
Unity3D小白,研究过程主要参考技术博客如下:
Unity技术博客 - 客户端断点续传
转载合作相关事宜,请联系我的经纪人。额,还没有经纪人,联系本人,转载系出处,谢谢。
网友评论