Unity异步加载AssetBundle方案,4.x版本资源加载(5.x版本资源可以参考插件AssetBundleManager)
来源:互联网 发布:sql建立唯一索引 编辑:程序博客网 时间:2024/05/16 07:58
提升资源加载速度,不卡主线程的加载方式
using UnityEngine;using System.Collections; public abstract class AssetBundleLoadOperation : IEnumerator { public object Current { get { return null; } } public bool MoveNext() { return !IsDone(); } public void Reset() { } abstract public bool Update(); abstract public bool IsDone(); } public class AssetBundleLoadLevelOperation : AssetBundleLoadOperation { protected string m_AssetBundleName;//资源名 protected string m_LevelName;//场景名 protected bool m_IsAdditive; protected string m_DownloadingError;//下载错误信息 protected AsyncOperation m_Request; #region//场景加载 public AssetBundleLoadLevelOperation(string assetbundleName, string levelName, bool isAdditive) { m_AssetBundleName = assetbundleName; m_LevelName = levelName; m_IsAdditive = isAdditive; } public override bool Update() { if (m_Request != null) return false; LoadedAssetBundle bundle = AssetBundleManager.GetLoadedAssetBundle(m_AssetBundleName, out m_DownloadingError); if (bundle != null) { if (m_IsAdditive) m_Request = Application.LoadLevelAdditiveAsync(m_LevelName); else m_Request = Application.LoadLevelAsync(m_LevelName); return false; } else return true; } public override bool IsDone() { // Return if meeting downloading error. // m_DownloadingError might come from the dependency downloading. if (m_Request == null && m_DownloadingError != null) { Debug.LogError(m_DownloadingError); return true; } return m_Request != null && m_Request.isDone; } } #endregion public abstract class AssetBundleLoadAssetOperation : AssetBundleLoadOperation { public abstract T GetAsset<T>() where T : UnityEngine.Object; } public class AssetBundleLoadAssetOperationFull : AssetBundleLoadAssetOperation { protected string m_AssetBundleName; protected string m_DownloadingError; protected System.Type m_Type; protected AssetBundleRequest m_Request = null; public AssetBundleLoadAssetOperationFull(string bundleName, System.Type type) { m_AssetBundleName = bundleName; m_Type = type; } public override T GetAsset<T>() { if (m_Request != null && m_Request.isDone) return m_Request.asset as T; else return null; } // Returns true if more Update calls are required. public override bool Update() { if (m_Request != null) return false; LoadedAssetBundle bundle = AssetBundleManager.GetLoadedAssetBundle(m_AssetBundleName, out m_DownloadingError); if (bundle != null) { ///@TODO: When asset bundle download fails this throws an exception... m_Request = bundle.m_AssetBundle.LoadAllAssetsAsync(m_Type); return false; } else { return true; } } public override bool IsDone() { // Return if meeting downloading error. // m_DownloadingError might come from the dependency downloading. if (m_Request == null && m_DownloadingError != null) { Debug.LogError(m_DownloadingError); return true; } return m_Request != null && m_Request.isDone; } }
using System.Collections;using System.Collections.Generic;using UnityEngine;public class LoadedAssetBundle{ public AssetBundle m_AssetBundle;//assetbundle资源 public int m_ReferencedCount;//引用数量 public LoadedAssetBundle(AssetBundle assetBundle) { m_AssetBundle = assetBundle; m_ReferencedCount = 1; }}public class AssetBundleManager : MonoBehaviour { static string m_BaseDownloadingURL = "";//加载地址(采用下载地址+文件名) static Dictionary<string, LoadedAssetBundle> m_LoadedAssetBundles = new Dictionary<string, LoadedAssetBundle>(); //下载的资源 static Dictionary<string, WWW> m_DownloadingWWWs = new Dictionary<string, WWW>(); //下载列表 static Dictionary<string, string> m_DownloadingErrors = new Dictionary<string, string>(); //下载错误信息 static List<AssetBundleLoadOperation> m_InProgressOperations = new List<AssetBundleLoadOperation>(); //进度信息 //static Dictionary<string, string[]> m_Dependencies = new Dictionary<string, string[]>(); //依赖信息 //加载地址 public static string BaseDownloadingURL { get { return m_BaseDownloadingURL; } set { m_BaseDownloadingURL = value; } } //获取StreamingAssets路径 private static string GetStreamingAssetsPath() { if (Application.isEditor) return "file://" + System.Environment.CurrentDirectory.Replace("\\", "/"); // Use the build output folder directly. else if (Application.isWebPlayer) return System.IO.Path.GetDirectoryName(Application.absoluteURL).Replace("\\", "/") + "/StreamingAssets"; else if (Application.isMobilePlatform || Application.isConsolePlatform) return Application.streamingAssetsPath; else // For standalone player. return "file://" + Application.streamingAssetsPath; } //获取已加载资源 static public LoadedAssetBundle GetLoadedAssetBundle(string assetBundleName, out string error) { if (m_DownloadingErrors.TryGetValue(assetBundleName, out error)) return null; LoadedAssetBundle bundle = null; m_LoadedAssetBundles.TryGetValue(assetBundleName, out bundle); if (bundle == null) return null; // No dependencies are recorded, only the bundle itself is required. //string[] dependencies = null; //if (!m_Dependencies.TryGetValue(assetBundleName, out dependencies)) // return bundle; // Make sure all dependencies are loaded //foreach (var dependency in dependencies) //{ // if (m_DownloadingErrors.TryGetValue(assetBundleName, out error)) // return bundle; // // Wait all the dependent assetBundles being loaded. // LoadedAssetBundle dependentBundle; // m_LoadedAssetBundles.TryGetValue(dependency, out dependentBundle); // if (dependentBundle == null) // return null; //} return bundle; } //释放资源 static protected void UnloadAssetBundleInternal(string assetBundleName) { string error; LoadedAssetBundle bundle = GetLoadedAssetBundle(assetBundleName, out error); if (bundle == null) return; if (--bundle.m_ReferencedCount == 0) { bundle.m_AssetBundle.Unload(false); m_LoadedAssetBundles.Remove(assetBundleName); } } //下载列表下载 void Update() { // Collect all the finished WWWs. var keysToRemove = new List<string>(); foreach (var keyValue in m_DownloadingWWWs) { WWW download = keyValue.Value; // If downloading fails. if (download.error != null) { m_DownloadingErrors.Add(keyValue.Key, string.Format("Failed downloading bundle {0} from {1}: {2}", keyValue.Key, download.url, download.error)); keysToRemove.Add(keyValue.Key); continue; } // If downloading succeeds. if (download.isDone) { AssetBundle bundle = download.assetBundle; if (bundle == null) { m_DownloadingErrors.Add(keyValue.Key, string.Format("{0} is not a valid asset bundle.", keyValue.Key)); keysToRemove.Add(keyValue.Key); continue; } //Debug.Log("Downloading " + keyValue.Key + " is done at frame " + Time.frameCount); m_LoadedAssetBundles.Add(keyValue.Key, new LoadedAssetBundle(download.assetBundle)); keysToRemove.Add(keyValue.Key); } } // Remove the finished WWWs. foreach (var key in keysToRemove) { WWW download = m_DownloadingWWWs[key]; m_DownloadingWWWs.Remove(key); download.Dispose(); } // Update all in progress operations for (int i = 0; i < m_InProgressOperations.Count; ) { if (!m_InProgressOperations[i].Update()) { m_InProgressOperations.RemoveAt(i); } else i++; } } //内部获取资源 static protected bool LoadAssetBundleInternal(string assetBundleName) { // Already loaded. LoadedAssetBundle bundle = null; m_LoadedAssetBundles.TryGetValue(assetBundleName, out bundle); if (bundle != null) { bundle.m_ReferencedCount++; return true; } // @TODO: Do we need to consider the referenced count of WWWs? // In the demo, we never have duplicate WWWs as we wait LoadAssetAsync()/LoadLevelAsync() to be finished before calling another LoadAssetAsync()/LoadLevelAsync(). // But in the real case, users can call LoadAssetAsync()/LoadLevelAsync() several times then wait them to be finished which might have duplicate WWWs. if (m_DownloadingWWWs.ContainsKey(assetBundleName)) return true; WWW download = null; string url = m_BaseDownloadingURL + assetBundleName;//基础路径加上文件名 download = new WWW(url); m_DownloadingWWWs.Add(assetBundleName, download); return false; } // Load AssetBundle and its dependencies.加载资源 static protected void LoadAssetBundle(string assetBundleName) { // Check if the assetBundle has already been processed. bool isAlreadyProcessed = LoadAssetBundleInternal(assetBundleName); } // Load asset from the given assetBundle.异步加载资源 static public AssetBundleLoadAssetOperation LoadAssetAsync(string assetBundleName, System.Type type) { AssetBundleLoadAssetOperation operation = null; { LoadAssetBundle(assetBundleName); operation = new AssetBundleLoadAssetOperationFull(assetBundleName, type); m_InProgressOperations.Add(operation); } return operation; } #region//单例 // 定义一个静态变量来保存类的实例 private static AssetBundleManager instance; // 定义一个标识确保线程同步 private static readonly object locker = new object(); // 定义私有构造函数,使外界不能创建该类实例 private AssetBundleManager() { } /// <summary> /// 定义公有方法提供一个全局访问点,同时你也可以定义公有属性来提供全局访问点 /// </summary> /// <returns></returns> public static AssetBundleManager Instance() { // 当第一个线程运行到这里时,此时会对locker对象 "加锁", // 当第二个线程运行该方法时,首先检测到locker对象为"加锁"状态,该线程就会挂起等待第一个线程解锁 // lock语句运行完之后(即线程运行完之后)会对该对象"解锁" lock (locker) { // 如果类的实例不存在则创建,否则直接返回 if (instance == null) { GameObject tGO = new GameObject("AssetBundleManager"); tGO.AddComponent<AssetBundleManager>(); instance = tGO.GetComponent<AssetBundleManager>(); instance = new AssetBundleManager(); Debug.Log("@@ Creat AssetBundleManager"); } } return instance; } #endregion}
加载案例
void Start() { //异步加载资源+ AssetBundleManager.Instance(); AssetBundleManager.BaseDownloadingURL = PathManager.Instance().GetPath() + "101/New Folder/"; Debug.Log(AssetBundleManager.BaseDownloadingURL); StartCoroutine(InstantiateGameObjectAsync("Cube.u3d")); } protected IEnumerator InstantiateGameObjectAsync(string assetBundleName) { // This is simply to get the elapsed time for this phase of AssetLoading. float startTime = Time.realtimeSinceStartup; // Load asset from assetBundle. AssetBundleLoadAssetOperation request = AssetBundleManager.LoadAssetAsync(assetBundleName, typeof(GameObject)); if (request == null) { Debug.Log("request null"); yield break; } yield return StartCoroutine(request); // Get the asset. var prefab = request.GetAsset<GameObject>(); if (prefab != null) GameObject.Instantiate(prefab); // Calculate and display the elapsed time. float elapsedTime = Time.realtimeSinceStartup - startTime; Debug.Log((prefab == null ? " was not" : " was") + " loaded successfully in " + elapsedTime + " seconds"); }
阅读全文
1 0
- Unity异步加载AssetBundle方案,4.x版本资源加载(5.x版本资源可以参考插件AssetBundleManager)
- Unity教程之-Unity5.x版本AssetBundle加载研究
- AssetBundle打包、加载实例(5.X 版本根据AssetBundleName打包)
- unity AssetBundle 加载资源 笔记
- 【Unity】Unity5版本的AssetBundle打包方案之资源打包
- Cocos2d-x 3.0多线程异步资源加载
- Cocos2d-x 3.0多线程异步资源加载
- Cocos2d-x 3.0多线程异步资源加载
- Cocos2d-x 3.0多线程异步资源加载
- Unity的动态加载AssetBundle资源笔记。
- Cocos2d-x 3.x 异步加载资源和Loading界面
- AssetBundle-----资源加载(读取assetbundle)
- C# Unity用AssetBundle加载本地资源 (1)
- 【Cocos2d-X(2.x) 游戏开发系列之三】最新版本cocos2d-2.0-x-2.0.2使用资源加载策略
- Unity5.X AssetBundle加载
- 基于Unity5.x版本资源内存管理方案
- 【Cocos2d-x】新手自学(七)百分比读取进度加载图片资源到缓存(2.0.1版本)
- 【Cocos2d-x】新手自学(七)百分比读取进度加载图片资源到缓存(2.0.1版本)
- select 常用语句总结
- 从软件工程角度看大前端技术栈
- 【Scikit-Learn 中文文档】流形学习
- c# WebApi之接口返回类型详解
- scikit-learn 中文文档-概率校准-监督学习|ApacheCN
- Unity异步加载AssetBundle方案,4.x版本资源加载(5.x版本资源可以参考插件AssetBundleManager)
- hduoj 2000
- git常用命令总结
- python sklearn包----------交叉验证
- 前端面试中的最常见的算法问题
- java上传下载实例
- tomcat reload 时报web应用已停止,不能加载jdbc异常的解决方法
- 一键离线地图发布(工具软件下载) 使用教程
- MyBatis(7)--spring boot集成MyBatis,集成Druid批量更新报错multi-statement not allow