//工具类方法********************************************************************
//路径(相对路径)
public static string GetAssetBundlePath()
{
string outPath = GetPlatformPath() + "/" + GetPlatformName();
if (!Directory.Exists(outPath))
{
Directory.CreateDirectory(outPath);
}
return outPath;
#region 平台判断
//switch (Application.platform)
//{
// case RuntimePlatform.WindowsPlayer://exe
// break;
// case RuntimePlatform.WindowsEditor://unity
// break;
// case RuntimePlatform.IPhonePlayer:
// break;
// case RuntimePlatform.Android:
// break;
// default:
// break;
//}
#endregion
}
//获取不同平台的路径
private static string GetPlatformPath()
{
#if UNITY_EDITOR || UNITY_STANDALONE_WIN
return Application.streamingAssetsPath;
#endif
#if UNITY_IPHONE || UNITY_ANDROID
return Application.persistentDataPath;
#endif
}
//给不同平台创建不同的文件夹
private static string GetPlatformName()
{
#if UNITY_EDITOR || UNITY_STANDALONE_WIN
return "PC";
#endif
#if UNITY_IPHONE || UNITY_ANDROID
return "MOBLIE";
#endif
}
//加密(MD5)
public static string GetMD5Data(string filePath)
{
FileStream file = new FileStream(filePath, FileMode.Open);//直接打开
MD5 md5 = new MD5CryptoServiceProvider();
byte[] md5Bytes = md5.ComputeHash(file);//拿到MD5字节数组
file.Close();
//新建sb对象
StringBuilder strb = new StringBuilder();
for (int i = 0; i < md5Bytes.Length; i++)
{
strb.Append(md5Bytes[i].ToString("x2"));//利用sb拼接在一起
}
return strb.ToString();//转类型,传
}
//Editor中的扩展编辑脚本****************************************************************
//构建AB包
[MenuItem("Tools/Build Asset Bundle")]
static void BuildAssetBundles()
{
string path = Tools.GetAssetBundlePath();
BuildPipeline.BuildAssetBundles(path,BuildAssetBundleOptions.None,BuildTarget.StandaloneWindows64);
}
//获取构建的AB包的MD5 值 存起来
[MenuItem("Tools/Build File MD5")]
static void BuildFileMD5()
{
//string str = "";
string path = Tools.GetAssetBundlePath();//所有文件路径
string md5Path = Tools.GetAssetBundlePath() + "/md5.txt"; //保存md5数据文件路径
if (File.Exists(md5Path))//清空之前的
{
//str = File.ReadAllText(md5Path);
File.Delete(md5Path);
}
//MD5值到底如何储存(一个文件对应一个MD5)
//获取到了没有 获取路径
List<string> pathList = new List<string>();
GetFilePath(new DirectoryInfo(path),ref pathList);
StringBuilder sb = new StringBuilder();
//储存MD5
for (int i = 0; i < pathList.Count; i++)
{
//如何过滤掉 meta文件
string tempPath = pathList[i];
if (Path.GetExtension(tempPath) == ".meta")
continue;
string md5 = Tools.GetMD5Data(tempPath);
//str += "\r\n";
//str += md5;
//Debug.Log(md5);
//File.WriteAllText(md5Path,str);
string name = Path.GetFileName(tempPath);
sb.AppendLine(name + "|" + md5);
}
File.WriteAllText(md5Path,sb.ToString());
}
//拿到一个文件夹下方的所有文件路径
static void GetFilePath(DirectoryInfo directoryInfo,ref List<string> pathList)
{//out用法,一般用于需要返回多个参数时,如在需要返回分页的数据时 同时返回总条数或者TryParse()会用到
// *ref用法,一般用于在改变一个参数时,把他的改变反应到变量中 如在递归中
FileSystemInfo[] infos = directoryInfo.GetFileSystemInfos();
foreach (var item in infos)
{
FileInfo file = item as FileInfo;//file 不为空 证明是个文件
if (file != null)
{
//Debug.Log("文件" + file.FullName);
pathList.Add(file.FullName);
}
else
{
DirectoryInfo dir = item as DirectoryInfo;
//是个文件夹
//Debug.Log("文件夹" + dir.Name);
GetFilePath(dir,ref pathList);
}
}
}
/*
out、ref都是引用传递 (传递后改变传递的值会影响原来的值)
out不需要初始化 需要在传入的方法内部完成初始化赋值 ref必须初始化赋值
out用于获取函数内部的值 ref可同时改变函数内和函数外的值
*/
//unity上挂载的主脚本****************************************************************
private void Start()//开启一个协程
{
StartCoroutine(DownLoadResources());
}
IEnumerator DownLoadResources()
{
//url (服务器) 路径(本地)
string url = "http://192.168.25.136:8000/PC/";
string downloadPath = Tools.GetAssetBundlePath();
//下载服务器的md5 文件
string md5url = url + "md5.txt";
WWW www = new WWW(md5url);
yield return www;
//如果www出错 直接跳过协程
if (!string.IsNullOrEmpty(www.error))
{
Debug.LogError(www.error.ToString());
yield break;
}
File.WriteAllBytes(downloadPath+"/newMd5.txt",www.bytes);
//用这个服务器的MD5 值和每个文件的MD5 对比
string[] md5values = www.text.Split('\n');
foreach (var item in md5values)
{
Debug.Log(item);
}
for (int i = 0; i < md5values.Length; i++)
{
if (string.IsNullOrEmpty(md5values[i]))
continue;
//获取每个文件的文件名 和MD5 值
string[] values = md5values[i].Split('|');
string fileName = values[0];//文件名
//获取本地
//拼接出来
string localFilePath = (downloadPath + "/" + fileName).Trim();
//删去所有空格 及 各种字符
if (File.Exists(localFilePath))//文件存在(ab在 判断md5)
{
string fileMd5 = values[1].Trim();//服务器md5
string localMd5 = Tools.GetMD5Data(localFilePath);//本地MD5
if (localMd5.Equals(fileMd5))
{
print("本地的ab包是最新的,不需要更新!");
continue;
}
else
{
print("本地的和服务器的不同,需要下载最新ab包");
File.Delete(localFilePath);
}
}
else//文件不存在(没有ab包)
{
print("没有ab包");
}
//下载ab包
string tempurl = url + fileName;
WWW abw = new WWW(tempurl);
yield return abw;
if (!string.IsNullOrEmpty(abw.error))
{
Debug.LogError(abw.error.ToString());
yield break;
}
//保存本地
File.WriteAllBytes(localFilePath,abw.bytes);
}
}
//如果对比MD5一致的话就加载这个ab包
public void ABLoad()
{
string path = Tools.GetAssetBundlePath();
AssetBundle ab = AssetBundle.LoadFromFile(path + "/cube.ab");
GameObject cube = ab.LoadAsset<GameObject>("Cube");
Instantiate(cube);
}