AssetBundle管理器示例
//#define EDITOR_CODE_HIDE
//#define WECHAT
#define ANDROID_APK
//* StreamingAssets 不能写入 随包发包 适合存放一些初始化的AssetBundle资源 如 登入页 加载页等
//* PersistentData 适合存放 运行程序下载的AssetBundle资源
//StreamingAssets目录必须在Assets根目录下,该目录下所有资源也会被打包到游戏里,不同于Resources目录,该目录下的资源不会进行压缩,同样是只读不可写的。
//Unity基本也没有提供从该路径下直接读取资源的方法,只有www可以加载audioClip、texture和二进制文件。但Unity提供了从该目录加载AssetBundle的方法,我们一般直接在这个目录下存放AssetBundle文件。可以通过Application.streamingAssetsPath访问该路径。
//PersistentDataPath
//该目录为应用程序沙盒目录,应用程序安装后才会出现。该目录独特之处在于是可写的,所以我们一般将下载的AssetBundle存放于此。使用Application.persistentDataPath访问。
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using LitJson;
#if UNITY_EDITOR
using UnityEditor;
#endif
#if WECHAT
using WeChatWASM;
#endif
public class AssetBundleRequire
{
/// <summary>
/// 基本信息
/// </summary>
public string name; //包名
public int length; //文件长度
public string url; //下载地址
public string devicePath; //设备路径 -- (目前仅WX使用)
/// <summary>
/// 网络请求
/// </summary>
public UnityWebRequest request;
/// <summary>
/// 下载完成回调
/// </summary>
public UnityAction savedCallBack;
/// <summary>
/// 已下载保存
/// </summary>
public bool isSaved = false;
public float GetProgress()
{
if (isSaved)
{
return 1f;
}
else
{
if (request != null)
{
return request.downloadProgress;
}
else
{
return 0f;
}
}
}
public string GetProgressText()
{
if (isSaved)
{
return "(完毕)";
}
else
{
if (request != null)
{
return (request.downloadedBytes / 1000) + "kb/" + (length / 1000) + "kb";
}
else
{
return "(unknown)";
}
}
}
public AssetBundleRequire(string name, int length, string url)
{
this.name = name; this.length = length; this.url = url; this.devicePath = ""; this.savedCallBack = null;
#if UNITY_EDITOR && !EDITOR_CODE_HIDE
this.devicePath = "";
#elif WECHAT
this.devicePath = WX.env.USER_DATA_PATH + "/CWJLDMX/" + this.name;
#endif
}
}
public class AssetBundleManager : MonoBehaviour
{
// -------------------------------单例 ------------------------------------------------
private static AssetBundleManager inst = null;
public static AssetBundleManager Instance {
get
{
if (inst == null)
inst = FindObjectOfType<AssetBundleManager>();
return inst;
}
}
// ------------------------------ 容器 ------------------------------------------------
[HideInInspector] public AssetBundleRequire[] basicAssetBundles = null;
[HideInInspector] public AssetBundleRequire[] nonBasicAssetBundles = null;
[HideInInspector] public List<AssetBundleRequire> appendAssetBundles = new List<AssetBundleRequire>();
[HideInInspector] public Queue<AssetBundleRequire> remainRequires = null;
[HideInInspector] public List<AssetBundleRequire> downloadingRequires = null;
// ---------------------------------------- 外部接口 ----------------------------------------
/// <summary>
/// 基础包全部载入事件回调
/// </summary>
[HideInInspector] public UnityEvent onAllBasicBundlesLoaded = new UnityEvent();
/// <summary>
/// 下一场景异步加载完成回调
/// </summary>
[HideInInspector] public UnityEvent onNextSceneReady = new UnityEvent();
/// <summary>
/// 基本包已全部载入
/// </summary>
public bool AllLoaded => this.allLoaded;
/// <summary>
/// 新进入的玩家
/// </summary>
public bool IsNewEnter => this.isNewEnter;
/// <summary>
/// 基本包已下载字节数
/// </summary>
public int DownloadedBytes => this.GetDownloadedBytes();
/// <summary>
/// 基本包总字节数
/// </summary>
public int TotalBytes => this.GetTotalBytes();
/// <summary>
/// 新的附加AB包请求
/// </summary>
public AssetBundleRequire NewRequireBundle(string name, UnityAction callback)
{
AssetBundleRequire newRequire = nonBasicAssetBundles.FirstOrDefault(ab => ab.name == name.ToLower());
Debug.Log("下载附加包:" + name.ToLower());
if(newRequire != null)
{
// *** 附加到Append列表 ***
if (!appendAssetBundles.Contains(newRequire))
{
appendAssetBundles.Add(newRequire);
}
// *** 已下载或者下载 ***
if (newRequire.isSaved)// -- 已下载 --
{
Debug.Log("已下载过该AB包!");
newRequire.savedCallBack = callback;
newRequire.savedCallBack?.Invoke();
return newRequire;
}
else // -- 未下载 --
{
if (appendAssetBundles.Contains(newRequire))// -- 已经申请下载过 --
{
Debug.Log("下载中");
newRequire.savedCallBack = callback;
return newRequire;
}
else // -- 未申请下载过 --
{
Debug.Log("开始下载");
newRequire.savedCallBack = callback;
//加入下载队列
appendAssetBundles.Add(newRequire);
remainRequires.Enqueue(newRequire);
return newRequire;
}
}
}
else
{
Debug.LogAssertion("AB包名错误:" + name.ToLower());
Debug.LogAssertion("可以下载的非必要包列表:" + string.Concat(nonBasicAssetBundles.Select(abr=>abr.name + "\n")));
return null;
}
}
// ---------------------------------------- 参数 ----------------------------------------
[Header("同时下载的文件大小(参考值)")]
public int refLength = 2000000; // 2mb //同时下载的文件长度参考
[Header("下载AB包的服务器URL")]
public string serverABUrl = "https://cdn.888xin.top/minigame/UnityWebZoo/AssetBundles/";
[Header("AB包版本")]
public string assetVersion = "";
// ---------------------------------------- 状态相关 ----------------------------------------
//STATUS
[HideInInspector] public int runtime = 0;
private bool allLoaded = false;
private bool isNewEnter = false;
// ---------------------------------------- 日志 ----------------------------------------
private List<string> logList = new List<string>();
#if UNITY_EDITOR && !EDITOR_CODE_HIDE
#elif ANDROID_APK
#elif WECHAT
private string localDir = WX.env.USER_DATA_PATH + "/CWJLDMX";
//微信文件管理器
private WXFileSystemManager mgr = null;
#endif
void Awake()
{
inst = this;
}
void Start()
{
DontDestroyOnLoad(this.gameObject);
//比较资源版本 --> 清除文件缓存
if (this.assetVersion != PlayerPrefs.GetString("assetVersion", ""))
{
CleanFilesCache_General();
Debug.Log("资源版本比较不一致...清除资源文件...");
}
else
{
Debug.Log("资源版本比较一致...");
}
//(平台无关)生成基本/非基本AB包需求信息
GenAbRequires();
//(平台无关)判断是否已存在文件
List<AssetBundleRequire> allabr = new List<AssetBundleRequire>(basicAssetBundles); allabr.AddRange(nonBasicAssetBundles);
foreach (var require in allabr)
{
if (ExistFile_General(require))
{
require.isSaved = true;
}
else
{
require.isSaved = false;
}
}
//必须下载的AB包
remainRequires = new Queue<AssetBundleRequire>(basicAssetBundles.Where(r => r.isSaved == false).OrderBy(r => r.length));
downloadingRequires = new List<AssetBundleRequire>();
//新用户
isNewEnter = basicAssetBundles.All(r => r.isSaved == false);
//开始下载埋点
if (isNewEnter)
{
MaiDian.Mai("number", 1, "version", Infomanager.MaiDianVersion, "enterGameLoading");
}
#if UNITY_EDITOR && !EDITOR_CODE_HIDE
#elif ANDROID_APK
#elif WECHAT
WX.SetGameStage(0);
// WX FILE MANAGER
mgr = WX.GetFileSystemManager();
#endif
}
private void Update()
{
if (basicAssetBundles == null) return;
//运行时间
runtime += 1;
//下载
ProcessDownloading();
//基本包加载完成
if (allLoaded) return;
if (!allLoaded && basicAssetBundles.All(rq => rq.isSaved == true))
{
allLoaded = true;
#if UNITY_EDITOR && !EDITOR_CODE_HIDE
//Debug.Log("");
#elif ANDROID_APK
//Debug.Log("");
#elif WECHAT
WX.SetGameStage(1);
#endif
//下载完成埋点
if (isNewEnter)
{
MaiDian.Mai("number", 2, "version", Infomanager.MaiDianVersion, "enterGameLoading");
}
//SET RES
SetResourceBundle();
#if UNITY_EDITOR && !EDITOR_CODE_HIDE
//Debug.Log("");
#elif ANDROID_APK
//Debug.Log("");
#elif WECHAT
WX.ReportGameStart();
#endif
//更新资源版本
PlayerPrefs.SetString("assetVersion", this.assetVersion);
////自动异步加载下一场景
//ReadyNextScene();
//全部下载完成事件
onAllBasicBundlesLoaded?.Invoke();
}
}
// ------------------------------------------------------------------------------------- 文件下载和IO ----------------------------------------------------------------------------
//(Editor下载到StreamAssets / 读取:直接从StreamAssets读取)
//(安卓下载到Persistent目录 / 读取:可以从StreamingAsset读取也可以从Persistent目录读取)
//(微信小程序:使用提供的API接口)
/// <summary>
/// 平台无关 读取AB包需求
/// </summary>
private void GenAbRequires()
{
JsonData jreq = JsonMapper.ToObject(Resources.Load<TextAsset>("AssetBundles").text);
JsonData jbasicAbs = jreq["basic"];
AssetBundleRequire[] requiresBasic = new AssetBundleRequire[jbasicAbs.Count];
for (int i = 0; i < requiresBasic.Length; ++i)
{
requiresBasic[i] = new AssetBundleRequire((string)jbasicAbs[i]["file"], (int)jbasicAbs[i]["size"], serverABUrl + (string)jbasicAbs[i]["file"]);
}
this.basicAssetBundles = requiresBasic;
if (jreq.ContainsKey("non-basic"))
{
JsonData jnonBasicAbs = jreq["non-basic"];
AssetBundleRequire[] requiresNonBasic = new AssetBundleRequire[jnonBasicAbs.Count];
for (int i = 0; i < requiresNonBasic.Length; ++i)
{
requiresNonBasic[i] = new AssetBundleRequire((string)jnonBasicAbs[i]["file"], (int)jnonBasicAbs[i]["size"], serverABUrl + (string)jnonBasicAbs[i]["file"]);
}
this.nonBasicAssetBundles = requiresNonBasic;
}
else
{
this.nonBasicAssetBundles = new AssetBundleRequire[0];
}
}
/// <summary>
/// 平台无关 清除文件缓存
/// </summary>
public void CleanFilesCache_General()
{
#if UNITY_EDITOR && !EDITOR_CODE_HIDE
DirectoryInfo streamingAssetDir = new DirectoryInfo(Application.streamingAssetsPath);
foreach (var f in streamingAssetDir.GetFiles())
{
if (f.Extension.Contains("ab") || f.Extension.Contains("manifest"))
{
System.IO.File.Delete(f.FullName);
}
}
#elif ANDROID_APK
DirectoryInfo persistantDir = new DirectoryInfo(Application.persistentDataPath);
foreach (var f in persistantDir.GetFiles())
{
if (f.Extension.Contains("ab") || f.Extension.Contains("manifest"))
{
System.IO.File.Delete(f.FullName);
}
}
#elif WECHAT
Debug.LogAssertion("删除所有文件 未实现");
#endif
}
/// <summary>
/// 平台无关 开始下载
/// </summary>
public void StartDownload_General(AssetBundleRequire req)
{
#if UNITY_EDITOR && !EDITOR_CODE_HIDE
StartCoroutine(EditorDownLoadAndSave(req));
#elif ANDROID_APK
StartCoroutine(AndroidDownloadAndSave(req));
#elif WECHAT
StartCoroutine(WXDownLoadAndSave(req));
#endif
}
/// <summary>
/// 平台无关 读取AssetBundle包
/// </summary>
public AssetBundle ReadAssetBundle_General(AssetBundleRequire req)
{
#if UNITY_EDITOR && !EDITOR_CODE_HIDE
return ReadBundleAtStreaming(req.name);
#elif ANDROID_APK
return ReadBundleAndroid(req.name);
#elif WECHAT
return ReadBundleAtFilePath(req.devicePath);
#endif
return null;
}
/// <summary>
/// 平台无关 是否存在文件
/// </summary>
public bool ExistFile_General(AssetBundleRequire require)
{
#if UNITY_EDITOR && !EDITOR_CODE_HIDE
return File.Exists(Application.streamingAssetsPath + "/" + require.name);
#elif ANDROID_APK
// ---------------- 先在StreamingAsset中查找 --------------------------------
UnityWebRequest localReq = UnityWebRequest.Get(Application.streamingAssetsPath + "/" + require.name);
localReq.SendWebRequest();
//while (!localReq.isDone && localReq.error == null) { }
if (localReq.error == null)
{
logList.Add("存在本地文件");
localReq.downloadHandler.Dispose();
return true;
}
// ---------------- 然后在Persistent下载中查找 --------------------------------
bool existAtPersistent = File.Exists(Application.persistentDataPath + "/" + require.name);
if (existAtPersistent)
{
logList.Add("存在本地文件");
return true;
}
#elif WECHAT
return ExistWXFile(require.devicePath);
#endif
logList.Add("不存在本地文件");
return false;
}
/// <summary>
/// 平台无关 比较清单
/// </summary>
public void CompareMinifest_General(AssetBundleRequire req)
{
//...
}
// -------------------------------------------------- Download && Save -----------------------------------------------------------------------------
/// <summary>
/// 加载AB包(从StreamingAsset目录)
/// </summary>
private AssetBundle ReadBundleAtStreaming(string abname)
{
AssetBundle ab = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + abname);
return ab;
}
/// <summary>
/// 编辑器下载,保存到StreamingAsset目录
/// </summary>
IEnumerator EditorDownLoadAndSave(AssetBundleRequire abRequire)
{
//UnityWebRequestAssetBundle.GetAssetBundle(string uri)使用这个API下载回来的资源它是不支持原始数据访问的.
UnityWebRequest request = UnityWebRequest.Get(abRequire.url);
request.downloadHandler = new DownloadHandlerBuffer();
request.timeout = 300;
abRequire.request = request;
request.SendWebRequest();
while (!request.isDone)
{
yield return null;
}
//下载状态.
if (request.isNetworkError || request.isHttpError)
{
UIMiniPoper.PopText("网络错误!");
}
else
{
EditorSave(abRequire, request);
}
}
private void EditorSave(AssetBundleRequire abRequire, UnityWebRequest request)
{
//构造文件流.
FileStream fs = File.Create(Application.streamingAssetsPath + "/" + abRequire.name);
//将字节流写入文件里,request.downloadHandler.data可以获取到下载资源的字节流.
fs.Write(request.downloadHandler.data, 0, request.downloadHandler.data.Length);
//文件写入存储到硬盘,关闭文件流对象,销毁文件对象.
fs.Flush();
fs.Close();
fs.Dispose();
abRequire.isSaved = true;
abRequire.savedCallBack?.Invoke();
Debug.Log("文件" + abRequire.name + "已经下载保存");
}
#if ANDROID_APK
/// <summary>
/// 安卓读取AB包
/// </summary>
private AssetBundle ReadBundleAndroid(string abname)
{
AssetBundle ab = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + abname);
if(ab != null)
{
return ab;
}
ab = AssetBundle.LoadFromFile(Application.persistentDataPath + "/" + abname);
return ab;
}
/// <summary>
/// 安卓分包下载
/// </summary>
/// <param name="abRequire"></param>
/// <returns></returns>
IEnumerator AndroidDownloadAndSave(AssetBundleRequire abRequire)
{
//UnityWebRequestAssetBundle.GetAssetBundle(string uri)使用这个API下载回来的资源它是不支持原始数据访问的.
UnityWebRequest request = UnityWebRequest.Get(abRequire.url);
request.downloadHandler = new DownloadHandlerBuffer();
request.timeout = 300;
abRequire.request = request;
request.SendWebRequest();
while (!request.isDone)
{
yield return null;
}
//下载状态.
if (request.isNetworkError || request.isHttpError)
{
UIMiniPoper.PopText("网络错误!");
}
else
{
AndroidSave(abRequire, request);
}
}
private void AndroidSave(AssetBundleRequire abRequire, UnityWebRequest request)
{
//构造文件流.
FileStream fs = File.Create(Application.persistentDataPath + "/" + abRequire.name);
//将字节流写入文件里,request.downloadHandler.data可以获取到下载资源的字节流.
fs.Write(request.downloadHandler.data, 0, request.downloadHandler.data.Length);
//文件写入存储到硬盘,关闭文件流对象,销毁文件对象.
fs.Flush();
fs.Close();
fs.Dispose();
abRequire.isSaved = true;
abRequire.savedCallBack?.Invoke();
Debug.Log("文件" + abRequire.name + "已经下载保存");
}
#endif
#if WECHAT
bool ExistWXFile(string path)
{
var result = mgr.AccessSync(path);
return result == "access:ok";
}
IEnumerator WXDownLoadAndSave(AssetBundleRequire abRequire)
{
//UnityWebRequestAssetBundle.GetAssetBundle(string uri)使用这个API下载回来的资源它是不支持原始数据访问的.
UnityWebRequest request = UnityWebRequest.Get(abRequire.url);
request.downloadHandler = new DownloadHandlerBuffer();
request.timeout = 300;
abRequire.request = request;
request.SendWebRequest();
while (!request.isDone)
{
yield return null;
}
//下载状态.
if (request.isNetworkError || request.isHttpError)
{
UIMiniPoper.PopText("网络错误!");
}
else
{
WXSave(abRequire, request);
}
}
private void WXSave(AssetBundleRequire abRequire, UnityWebRequest request)
{
////构造文件流.
//FileStream fs = File.Create(Application.streamingAssetsPath + "/" + fileName);
////将字节流写入文件里,request.downloadHandler.data可以获取到下载资源的字节流.
//fs.Write(request.downloadHandler.data, 0, request.downloadHandler.data.Length);
////文件写入存储到硬盘,关闭文件流对象,销毁文件对象.
//fs.Flush();
//fs.Close();
//fs.Dispose();
//Debug.Log(fileName + "下载完毕");
mgr.MkdirSync(localDir, true);
mgr.WriteFileSync(abRequire.devicePath, request.downloadHandler.data);
abRequire.isSaved = true;
abRequire.savedCallBack?.Invoke();
Debug.Log("文件" + abRequire.name + "已经下载保存");
}
/// <summary>
/// 加载AB包
/// </summary>
private AssetBundle ReadBundleAtFilePath(string localpath)
{
byte[] data = mgr.ReadFileSync(localpath);
var ab = AssetBundle.LoadFromMemory(data);
return ab;
}
#endif
/// <summary>
/// 加载读取资源AB包
/// </summary>
private void SetResourceBundle()
{
AssetBundleRequire[] resourcesBundlesReq = basicAssetBundles.Where(abr => abr.name.Contains("resources")).ToArray();
ResourceBundle.resAbs = resourcesBundlesReq.Select(req => ReadAssetBundle_General(req)).ToList();
}
/// <summary>
/// 下载处理
/// </summary>
private void ProcessDownloading()
{
if (downloadingRequires.Count < 1 && remainRequires.Count < 1) return;
//当前同时下载的文件总大小
int currentSize = downloadingRequires.Sum(r => r.length);
//检查下载队列
if (downloadingRequires.Count > 0)
{
if (downloadingRequires.Any(r => r.isSaved == true))
{
var finishTask = downloadingRequires.FirstOrDefault(r => r.isSaved == true);
if (finishTask != null)
{
downloadingRequires.Remove(finishTask);
}
}
}
//检查待下载队列
if(remainRequires.Count > 0)
{
//新的下载任务
if (currentSize < refLength)
{
var newdownload = remainRequires.Dequeue();
//加入加载队列
downloadingRequires.Add(newdownload);
//开始下载
StartDownload_General(newdownload);
}
}
}
/// <summary>
/// 所有AB包的总字节数
/// </summary>
/// <returns></returns>
private int GetTotalBytes()
{
if (basicAssetBundles != null)
{
int sum = 0;
foreach (var r in basicAssetBundles)
{
sum += r.length;
}
return sum;
}
else
{
return 99999;
}
}
/// <summary>
/// 已下载AB包的字节数
/// </summary>
/// <returns></returns>
private int GetDownloadedBytes()
{
if (basicAssetBundles != null)
{
int sum = 0;
foreach (var r in basicAssetBundles)
{
if (r.isSaved)
{
sum += r.length;
}
}
return sum;
}
else
{
return 0;
}
}
// **************************************************** 场景加载相关 ******************************************************************
/// <summary>
/// 载入场景(没在AB包就默认为在主包中)
/// </summary>
/// <param name="sceneName"></param>
/// <param name="callback"></param>
public void LoadScene(string sceneName, UnityAction<AsyncOperation> callback = null)
{
StartCoroutine(CoLoadScene(sceneName, callback));
}
private List<AssetBundle> sceneAbLoaded = new List<AssetBundle>();
private IEnumerator CoLoadScene(string sceneName, UnityAction<AsyncOperation> callback = null)
{
// *** 是否在BuildSetting中 ***
bool isInBuildinScenes = false;
for (int i = 0; i < SceneManager.sceneCountInBuildSettings; i++)
{
var s = SceneManager.GetSceneByBuildIndex(i);
var path = SceneUtility.GetScenePathByBuildIndex(i);
string sName = System.IO.Path.GetFileNameWithoutExtension(path);
//Debug.Log("scene path:" + path);
//Debug.Log("scene name1:" + s.name);
//Debug.Log("scene Name2:" + sName);
if (sName == sceneName)
{
isInBuildinScenes = true;
}
}
// *** 如果场景不在BuildSetting中就下载并加载AB包 ***
if (isInBuildinScenes)
{
}
else
{
var req = NewRequireBundle(sceneName.ToLower() + ".ab", () => { });
yield return new WaitUntil(() => req.isSaved);
AssetBundle ab = ReadAssetBundle_General(req);
sceneAbLoaded.Add(ab);
}
// *** 开始异步加载场景 ***
yield return new WaitForSeconds(0.1f);//如果没有这行会导致allowSceneActivation=false失效
var nextSceneLoadOp = UnityEngine.SceneManagement.SceneManager.LoadSceneAsync(sceneName);
nextSceneLoadOp.allowSceneActivation = false;
yield return new WaitForSeconds(0.5f);
while (nextSceneLoadOp.progress < 0.9f)
{
yield return null;
}
callback?.Invoke(nextSceneLoadOp);
}
/// <summary>
/// 卸载场景包
/// </summary>
public void UnloadAllSceneAb()
{
AssetBundle[] arr = sceneAbLoaded.ToArray();
foreach(var ab in arr)
{
Debug.Log("场景包:" + ab.name + " 正在卸载...");
sceneAbLoaded.Remove(ab);
ab.Unload(true);
}
}
public void OnGUI()
{
if (allLoaded) return;
// --------------------------------------------------------
//if (allLoaded) return;
//StringBuilder strb = new StringBuilder();
//strb.Append("basic:\n");
//foreach(var ab in this.basicAssetBundles)
//{
// strb.Append(ab.name + "progress:" + ab.GetProgress() + " isSvaed:" + ab.isSaved + "\n");
//}
//strb.Append("non - basic:\n");
//foreach (var ab in this.nonBasicAssetBundles)
//{
// strb.Append(ab.name + "progress:" + ab.GetProgress() + " isSvaed:" + ab.isSaved + "\n");
//}
//GUILayout.TextArea(strb.ToString());
// --------------------------------------------------------
StringBuilder strb = new StringBuilder();
foreach(var log in logList)
{
strb.Append(log);
strb.Append("\n");
}
GUILayout.TextArea(strb.ToString());
}
}
#if UNITY_EDITOR
[CustomEditor(typeof(AssetBundleManager))]
public class CustomAssetBundleManager : Editor
{
private GUIStyle style = null;
private AssetBundleManager mgr = null;
private bool inited = false;
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if(!inited)
{
mgr = target as AssetBundleManager;
style = new GUIStyle() { richText = true };
inited = true;
}
GUILayout.Space(50);
GUILayout.BeginVertical("frameBox");
//基本包
GUILayout.Label(" *** 游戏运行所需基本包 ***");
GUILayout.BeginVertical("frameBox");
if (mgr.basicAssetBundles != null)
{
for (int i = 0; i < mgr.basicAssetBundles.Length; i++)
{
GUILayout.Space(20);
var lastRect = GUILayoutUtility.GetLastRect();
float progress = mgr.basicAssetBundles[i].GetProgress();
bool isSaved = mgr.basicAssetBundles[i].isSaved;
string colorRgb = isSaved ? "#FFFFFF" : "#444444";
string progressText = mgr.basicAssetBundles[i].GetProgressText();
GUI.DrawTexture(new Rect(lastRect.x + 300, lastRect.y, 204f, 20), Texture2D.grayTexture);
GUI.DrawTexture(new Rect(lastRect.x + 302, lastRect.y + 5, 200f * progress , 10), Texture2D.whiteTexture);
GUI.Label(lastRect, "<color=" + colorRgb + ">" + mgr.basicAssetBundles[i].name + "</color>", style);
GUI.Label(new Rect(lastRect.x + 500, lastRect.y, 100, 20), "<color=" + colorRgb + ">" + ( isSaved ? "已下载" : ("下载中" + progressText) ) + "</color>", style);
}
}
GUILayout.EndVertical();
//可下载附加包
GUILayout.Label(" *** 可下载附加包 ***");
GUILayout.BeginVertical("frameBox");
if (mgr.nonBasicAssetBundles != null)
{
for (int i = 0; i < mgr.nonBasicAssetBundles.Length; i++)
{
GUILayout.Space(20);
var lastRect = GUILayoutUtility.GetLastRect();
float progress = mgr.nonBasicAssetBundles[i].GetProgress();
bool isSaved = mgr.nonBasicAssetBundles[i].isSaved;
string colorRgb = isSaved ? "#FFFFFF" : "#444444";
string progressText = mgr.nonBasicAssetBundles[i].GetProgressText();
GUI.DrawTexture(new Rect(lastRect.x + 300, lastRect.y, 204f, 20), Texture2D.grayTexture);
GUI.DrawTexture(new Rect(lastRect.x + 302, lastRect.y + 5, 200f * progress, 10), Texture2D.whiteTexture);
GUI.Label(lastRect, "<color=" + colorRgb + ">" + mgr.nonBasicAssetBundles[i].name + "</color>", style);
GUI.Label(new Rect(lastRect.x + 500, lastRect.y, 100, 20), "<color=" + colorRgb + ">" + (isSaved ? "已下载" : ("下载中" + progressText)) + "</color>", style);
}
}
GUILayout.EndVertical();
//已添加附加包
GUILayout.Label(" *** 已添加附加包 ***");
GUILayout.BeginVertical("frameBox");
if(mgr.appendAssetBundles != null)
{
for (int i = 0; i < mgr.appendAssetBundles.Count; i++)
{
string colorRgb = mgr.appendAssetBundles[i].isSaved ? "#FFFFFF" : "#444444";
GUILayout.Label("<color=" + colorRgb + ">" + mgr.appendAssetBundles[i].name + "</color>", style);
}
}
GUILayout.EndVertical();
//下载队列
GUILayout.Label(" *** 待下载队列 ***");
GUILayout.BeginVertical("frameBox");
if (mgr.remainRequires != null)
{
foreach(var req in mgr.remainRequires)
{
GUILayout.Label("<color=#FFFFFF>" + req.name + "</color>", style);
}
}
GUILayout.EndVertical();
//下载中
GUILayout.Label(" *** 下载中 ***");
GUILayout.BeginVertical("frameBox");
if (mgr.downloadingRequires != null)
{
foreach (var req in mgr.downloadingRequires)
{
GUILayout.Label("<color=#FFFFFF>" + req.name + "</color>", style);
}
}
GUILayout.EndVertical();
//。。。
GUILayout.EndVertical();
GUILayout.Label("<color=#333333>runtime:" + mgr.runtime + "</color>", style);
}
}
#endif