构建AB包
using System.Collections;
using System.Collections.Generic;using UnityEngine;
using UnityEditor;
using System.IO;
using System.Text;
public class CreateAssetBundle {
[MenuItem("Tools/Build Asset Bundle")]
static void BuildAssetBundle()
{
//构建AB包
string outPath = PathTools.GetAssetBundlePath();
BuildPipeline.BuildAssetBundles(outPath,BuildAssetBundleOptions.None,BuildTarget.StandaloneWindows64);
//BuildPipeline.BuildAssetBundles(,BuildAssetBundleOptions.None,BuildTarget.StandaloneWindows64);
}
/// <summary>
/// 构建AB包文件的MD5码
/// </summary>
[MenuItem("Tools/Build File MD5")]
static void BuildFileMD5()
{
string outDirPath = PathTools.GetAssetBundlePath();
string md5FilePath = outDirPath + "/md5.txt";//保存MD5 数据的文件
if (File.Exists(md5FilePath))
{
File.Delete(md5FilePath);
}
//获取所有AB包文件的路径
List<string> pathlist = new List<string>(); //存储所有文件的路径
GetFilePath(new DirectoryInfo(outDirPath),ref pathlist);
StringBuilder sb = new StringBuilder();
//存储MD5码
for (int i = 0; i <pathlist.Count; i++)
{
string filePath = pathlist[i];
//1.过滤文件
//获取文件拓展名
if (Path.GetExtension(filePath)==".meta")
{
continue;
}
string md5 = Tools.GetMD5HashFromFile(filePath);
//获取文件名
//字符串截取
//string name = filePath.Substring(filePath.LastIndexOf("\\")+1);
string[] names = filePath.Split('\\');
string name = names[names.Length - 1];
Debug.Log(name);
//2.存储MD5值
sb.Append(name+"|"+md5+"\n");
//sb.AppendLine(name + "|" + md5);//每次添加一次 换一次行
#region
//Debug.Log(md5);
//File.WriteAllText(md5FilePath,md5);
//AssetDatabase.Refresh();
//(2)方式二.过滤隐藏文件
//if (file != null)
//{
// if (file.Attributes != FileAttributes.Hidden)//判断状态 剔除隐藏文件
// {
// //Debug.Log("文件:"+ file.Name);
// //是文件
// pathlist.Add(file.FullName);
// }
//}
#endregion
}
File.WriteAllText(md5FilePath,sb.ToString());
AssetDatabase.Refresh();
}
//FileSystemInfo 文件系统类
//DirectoryInfo 文件夹信息类
//FileInfo 文件信息类
static void GetFilePath(DirectoryInfo directorinfo,ref List<string>pathlist)
{
//获取文件夹中所有文件的信息:文件夹或文件
FileSystemInfo[] infos = directorinfo.GetFileSystemInfos();
foreach (var item in infos)
{
FileInfo file = item as FileInfo;
//Debug.Log(file);//如果转成成功 为“是” ,则是一个文件 否则是一个文件夹
if (file!=null)
{
//是文件
pathlist.Add(file.FullName);
}
else
{
//是文件夹
DirectoryInfo dir = item as DirectoryInfo;
//递归调用
GetFilePath(dir, ref pathlist);
}
}
}
//Directory.Exists(outPath) 判断文件夹是否存在
//File.Exists(md5FilePath) 判断文件是否存在
//文件夹不存在时需要创建,否则无法使用该路径存储文件
//文件不存在时,不需要创建,当向文件中写入数据时会自动创建文件
}
Tools
using UnityEngine;
using System.IO;
using UnityEditor;
using System.Text;
/// <summary>
/// 工具类:获取路径 获取MD5码
/// </summary>
/// <summary>
/// 获取路径
/// </summary>
public class PathTools {
//根据不同平台获取AB包的路径
public static string GetAssetBundlePath()
{
string outPath = GetPlatformPath()+"/"+GetPlatformName();
if (!Directory.Exists(outPath))
{
//根据路径创建文件夹
Directory.CreateDirectory(outPath);
#if UNITY_EDITOR
AssetDatabase.Refresh();
#endif
}
return outPath;
}
/// <summary>
/// 获取平台的名字
/// </summary>
/// <returns></returns>
public static string GetPlatformName()
{
#if UNITY_EDITOR || UNITY_STANDALONE
return "PC";
#elif UNITY_IOS || UNITY_ANDROID
return "Mobile";
#endif
}
/// <summary>
/// 获取不同平台的路径
/// </summary>
/// <returns></returns>
public static string GetPlatformPath()
{
#if UNITY_EDITOR || UNITY_STANDALONE
return Application.streamingAssetsPath;
#elif UNITY_IOS || UNITY_ANDROID
return Application.persistentDataPath;
#endif
//switch (Application.platform)
//{
// case RuntimePlatform.OSXEditor:
// break;
// case RuntimePlatform.OSXPlayer:
// break;
// case RuntimePlatform.WindowsPlayer:
// break;
// case RuntimePlatform.WindowsEditor:
// break;
// case RuntimePlatform.IPhonePlayer:
// break;
// case RuntimePlatform.Android:
// break;
// default:
// break;
//}
//if (Application.isEditor)
//{
// //编辑模式
//}
//if (Application.isMobilePlatform)
//{
// //移动端
//}
}
}
public class Tools
{
/// <summary>
/// 获取MD5
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
public static string GetMD5HashFromFile(string filePath)
{
FileStream file = new FileStream(filePath, FileMode.Open);
System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] retVal = md5.ComputeHash(file);
file.Close();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < retVal.Length; i++)
{
sb.Append(retVal[i].ToString("x2"));
}
return sb.ToString().ToUpper();
}
}
GameInit
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.Text;
using System.IO;
public class GameInit : MonoBehaviour {
//递归调用例子 链表
List<int> numIndex = new List<int>();
void Start () {
//更新 下载 AB包
//string url = "http://192.168.25.139:8000/AssetBundles/md5.txt";
//根据AB包的名字找到对应的MD5值和本地的MD5值相比
//print(PathTools.GetAssetBundlePath());
//string md5 = Tools.GetMD5HashFromFile(PathTools.GetAssetBundlePath()+"/cube.ab");
//Debug.Log(md5);
//StringBuilder sb = new StringBuilder();
//sb.Append("a");
//sb.Append("b");
//sb.Append("d");
//sb.Append("f");
//print(sb.ToString());
//递归调用方法例子
//GetIndex(5);
//foreach (var item in numIndex)
//{
// Debug.Log(item);
//}
StartCoroutine("DownLoadResources");
}
IEnumerator DownLoadResources()
{
string downLownPath = PathTools.GetAssetBundlePath();
string url = "http://192.168.25.139:8000/AssetBundles/";
//下载MD5.Text文件
string md5Url = url + "md5.txt";
WWW www = new WWW(md5Url);
yield return www;
if (www.error!=null)
{
Debug.Log(www.error);
yield break;
}
Debug.Log("请求到md5"+www.text);//md5.txt的文本内容
//File.WriteAllText(downLownPath+"/newMD5.txt",www.text);
File.WriteAllBytes(downLownPath + "/newMD5.txt",www.bytes);
//获取所有的MD5值 包含文件名和MD5值
string[] md5Values = www.text.Split('\n');
for (int i = 0; i < md5Values.Length; i++)
{
//Debug.Log(md5Values[i]);
if (string.IsNullOrEmpty(md5Values[i]))
{
continue;//如果数组中元素为空跳过本次循环
}
//获取某个文件的名字和MD5值
string[] values = md5Values[i].Split('|');//["cube.ab",aad509ba04624..]
//Debug.Log(values[0]+":"+values[i]);
string filename = values[0];//文件名
//拼接本地AB包资源的路径
string localFilePath = (downLownPath + "/" + filename).Trim();
if (File.Exists(localFilePath))
{
//本地有AB包,比较MD5值
string md5 = values[1].Trim();//服务端获取的md5值
string localMD5 = Tools.GetMD5HashFromFile(localFilePath);//本地MD5值
if (localMD5.Equals(md5))
{
Debug.Log("本地已有最新的AB资源包");
continue;
}
else
{
Debug.Log("本地有AB包 但不是最新的 删除本地旧的AB包,从服务器下载最新的AB包");
File.Delete(localFilePath);
}
}
else
{
Debug.Log("本地没有AB包");
}
//下载AB包
Debug.Log("下载最新的AB包");
//"http://192.168.25.139:8000/AssetBundles/cube.ab";
string ABurl = url + filename;
WWW abwww = new WWW(ABurl);
yield return abwww;
if (abwww.error!=null)
{
Debug.Log(abwww.error);
yield break;
}
//abwww.text
//abwww.bytes
//保存下载的AB包到本地
File.WriteAllBytes(localFilePath,abwww.bytes);
}
//拿到服务器的MD5值
//如果本地没有AB包 先下载一次(首次使用,后期服务器更新 增加 新的资源)
//再次使用 : 找到某个AB包的MD5值和服务器中该文件的MD5值相比
//1. MD5值相同: 本地已有最新的AB包资源,不用更新
//2. MD5不相同: 本地有AB包,但不是最新的 删除本地旧的AB包,从服务器下载最新的AB包
//下载AB到本地包 然后从本地加载AB包(加载并没有保存到本地,下载保存到本地)
//加载AB包:本地、网络
AssetDatabase.Refresh();//刷新
LoadAB();
}
//从本地加载到场景
void LoadAB()
{
AssetBundle ab = AssetBundle.LoadFromFile("Assets/StramingAssets/PC/cube.ab");
//GameObject cube = ab.Load<GameObject>("cube");
// Instantiate(cube);
}
/// <summary>
/// 递归调用例子
/// </summary>
/// <param name="num"></param>
void GetIndex(int num)
{
int a = num - 1;
numIndex.Add(a);
if (a>0)
{
GetIndex(a);
}
}
}