unity3D热更新——(2)Assetbundle资源更新部分

论坛 期权论坛 脚本     
匿名网站用户   2020-12-20 22:32   11   0
///
///通过tomcat服务器进行下载ab包

///

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

public class UpdateAssetBundles : MonoBehaviour
{
/// <summary>
/// 配表路径
/// </summary>
List<string> mainPath;
/// <summary>
/// 配表信息
/// </summary>
Dictionary<string, List<string>> tablePath;
/// <summary>
/// 进入游戏进行资产更新
/// </summary>
public void FirstUpdateAB()
{
StartCoroutine(IEFirstUpdateAB());
}
IEnumerator IEFirstUpdateAB()
{
//进入游戏先检测persistent目录下是否有文件,没有则表示为第一次进游戏,
//需要将streaming目录下的文件拷贝到该目录下。
if (!Directory.Exists(AssetPath.persistentPath))
{
Debug.Log("解压本地文件!(该步骤不需要流量)");
//注意,在Android中,StreamingAssets中的文件包含在一个.jar压缩文件(基本上与标准的zip为统一格式)中,所以只能用
//WWW读取,否则要使用第三方软件来读取,不能用C#的文件读取方法。
List<string> streamList = new List<string>();
yield return StartCoroutine(IECStomcat(AssetPath.streamingPath + "/" + IP.preloadedPath, streamList));
string tableStr = "";
for (int i = 0; i < streamList.Count; i++)
{
tableStr += streamList[i];
tableStr += Environment.NewLine;
string relativePath = "/" + streamList[i].Split(';')[0];
yield return StartCoroutine(IEUpdateAssetBundle(Application.streamingAssetsPath + relativePath.Replace('\\','/'), Application.persistentDataPath + relativePath.Replace('\\', '/')));
}
Debug.Log("解压完成!");
CreadTextFile(AssetPath.persistentPath + "/" + IP.preloadedPath, tableStr);
yield return new WaitForSeconds(0);
}
//获取主配表
Debug.Log("获取服务器列表!(建议在WiFi下更新)");
mainPath = new List<string>();
yield return StartCoroutine(IECStomcat(IP.ResoucelsIP + AssetPath._Android + "/" + IP.ResoucelsTablePath, mainPath));
Debug.Log("检测是否需要更新!");
if (mainPath != null)
{
tablePath = new Dictionary<string, List<string>>();
for (int i = 0; i < mainPath.Count; i++)
{
List<string> list = new List<string>();
tablePath.Add(mainPath[i], list);
yield return StartCoroutine(IECStomcat(IP.ResoucelsIP + mainPath[i], list));
}
}
else
{
Debug.Log("服务器更新失败!找不到主配置文件!");
}
List<string> updateTable = ContrastDetection(tablePath);
Debug.Log("检测到有" + updateTable.Count + "个文件需要更新!");
yield return new WaitForSeconds(0.5f);
if (updateTable.Count > 0)
{
Debug.Log("开始更新资源文件!");
for (int i = 0; i < updateTable.Count; i++)
{
string serverPathAB = IP.ResoucelsIP + updateTable[i].Split(';')[0];
string localPathAB = Application.persistentDataPath + "/" + updateTable[i].Split(';')[0];
yield return StartCoroutine(IEUpdateAssetBundle(serverPathAB.Replace('\\', '/'), localPathAB.Replace('\\', '/')));
}
Debug.Log("资源文件已更新完毕!");
Debug.Log("开始更新配置文件!");
readText(tablePath);
yield return new WaitForSeconds(0.5f);
Debug.Log("配置文件已更新完成!");
}
Debug.Log("进入游戏!");
}




/// <summary>
/// 在安卓平台下判断该条路径是否为 "jar:file"开头(返回true为是)
/// </summary>
/// <returns></returns>
public bool jarFilePath(string path)
{
if (Application.platform == RuntimePlatform.Android && path.Substring(0, AssetPath.jarHead.Length) == AssetPath.jarHead)
{
return true;
}
return false;
}
/// <summary>
/// 判断该条路径是否为"http"开头(返回true为是)
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public bool httpPath(string path)
{
if (path.Substring(0, AssetPath.httpHead.Length) == AssetPath.httpHead)
{
return true;
}
return false;
}


/// <summary>
/// 获取配表,并把每行的信息写入列表中
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
IEnumerator IECStomcat(string path, List<string> mainPath)
{
string[] pathAll;
if (jarFilePath(path) || httpPath(path))
{
//这里有个问题,加了时间戳只有第一个链接能访问到
//if (httpPath(path))
//{
// string nn = DateTime.Now.Ticks.ToString();
// path = path + "?a=" + nn.Substring(nn.ToString().Length - 6);
//}
WWW www = new WWW(path);
yield return www;
if (www.error != null)
{
Debug.Log(www.error+" "+ path);
yield break;
}
pathAll = www.text.Split(Environment.NewLine.ToCharArray());
}
else
{
pathAll= File.ReadAllText(path).Split(Environment.NewLine.ToCharArray());
}
for (int i = 0; i < pathAll.Length; i++)
{
if (pathAll[i] != "")
{
mainPath.Add(pathAll[i]);
}
}
}
/// <summary>
/// 服务器配表与本地配表进行检测比对
/// </summary>
/// <param name="d"></param>
public List<string> ContrastDetection(Dictionary<string, List<string>> d)
{
string path = "";
List<string> listPath = new List<string>();
if (Application.platform == RuntimePlatform.WindowsEditor)
{
path = Application.dataPath + "/" + AssetPath.StreamingAssets;
}
else if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer)
{
path = Application.persistentDataPath;
}
//遍历配表
foreach (var item in d)
{
string file = "";
string localPath = path + "/" + item.Key;
//检测本地配表是否存在
if (File.Exists(localPath))
{
//本地有该配表就将路径进行比对添加到列表中
file = File.ReadAllText(localPath);
}
for (int i = 0; i < item.Value.Count; i++)
{
if (!file.Contains(item.Value[i]))
{
listPath.Add(item.Value[i]);
}
}
}
return listPath;
}
/// <summary>
/// 从服务器上下载ab包到本地,(注意斜杠,一定要把所有的反斜杠转成斜杠)
/// </summary>
/// <param name="path">服务器路径</param>
/// <param name="localPath">本地路径</param>
/// <returns></returns>
IEnumerator IEUpdateAssetBundle(string path, string localPath)
{
if (httpPath(path))
{
string nn = DateTime.Now.Ticks.ToString();
path = path + "?" + nn.Substring(nn.ToString().Length - 6);
}
WWW www = new WWW(path);
yield return www;
if (www.error != null)
{
Debug.Log("错误信息:" + www.error);
yield break;
}
else
{
string headLocalPath = pathRoundOff(localPath);
if (!Directory.Exists(headLocalPath))
{
Directory.CreateDirectory(headLocalPath);
}
if (File.Exists(localPath))
{
File.Delete(localPath);
}
FileStream steam = File.Create(localPath);
steam.Close();
File.WriteAllBytes(localPath, www.bytes);
}
}
/// <summary>
/// 更新配表
/// </summary>
/// <param name="dateList"></param>
public void readText(Dictionary<string, List<string>> dateList)
{

string directoryPath = Application.persistentDataPath + "/" + AssetPath._Android + "/" + AssetPath.ConfigurationFilesName;
//清除所有配表
if (Directory.Exists(directoryPath))
Directory.Delete(directoryPath, true);
Directory.CreateDirectory(directoryPath);
//创建新的配表
foreach (var item in dateList)
{
string loaclPath = Application.persistentDataPath + "/" + item.Key;
string str = "";
for (int i = 0; i < item.Value.Count; i++)
{
str += item.Value[i];
str += Environment.NewLine;
}
CreadTextFile(loaclPath, str);
}
}
/// <summary>
/// 创建文档文件
/// </summary>
/// <param name="path"></param>
/// <param name="str"></param>
public void CreadTextFile(string path, string str)
{
string headPath = pathRoundOff(path);
if (!Directory.Exists(headPath))
Directory.CreateDirectory(headPath);
File.WriteAllText(path, str);
}

/// <summary>
/// 截取文件的文件夹路径
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public string pathRoundOff(string path)
{
string[] newPath = path.Split('\\');
if (newPath.Length <= 1)
{
newPath = path.Split('/');
}
return path.Substring(0, path.Length - newPath[newPath.Length - 1].Length - 1);
}
}

public class AssetPath
{
/// <summary>
/// 需要打包的文件夹路径
/// </summary>
public static string OriginalPath = Application.dataPath + "/AssetBundleResources/Resources";
/// <summary>
/// 打包出来的文件夹路径
/// </summary>
public const string StreamingAssetsPath = @"Assets/StreamingAssets";
/// <summary>
/// 配置文件夹
/// </summary>
public const string ConfigurationFilesName = "configuration";
/// <summary>
/// 资源文件夹
/// </summary>
public const string ResourcesFilesName = "resources";
/// <summary>
/// 资源文件后缀名
/// </summary>
public const string unity3dSuffix = ".unity3d";
/// <summary>
/// .meta后缀名
/// </summary>
public const string metaSuffix = ".meta";
/// <summary>
/// 打包目录
/// </summary>
public const string StreamingAssets = "StreamingAssets";
/// <summary>
/// Android
/// </summary>
public const string _Android = "Android";
/// <summary>
/// IPhonePlayer
/// </summary>
public const string _IPhonePlayer = "IPhonePlayer";
/// <summary>
/// 移动端本地压缩包路径
/// </summary>
public static string streamingPath = Application.streamingAssetsPath + "/" + Application.platform;
/// <summary>
/// 移动端资产放置路径
/// </summary>
public static string persistentPath = Application.persistentDataPath + "/" + Application.platform;
/// <summary>
/// 预留物配表相对路径
/// </summary>
public const string scheduledFileName = "/"+ConfigurationFilesName+"/prefad/scheduled.txt";
/// <summary>
/// "jar:file"
/// </summary>
public const string jarHead = "jar:file";
/// <summary>
/// "http"
/// </summary>
public const string httpHead = "http";

/// <summary>
/// 配置物
/// </summary>
public const string source = "source";

}


分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1136255
帖子:227251
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP