您的位置:首页 > 移动开发 > Unity3D

Unity3D 游戏项目实例教程之资源加载管理器

2015-03-20 14:40 387 查看
资源加载管理器,顾名思义,就是负责加载资源的, Unity 中负责加载资源的是 WWW 类,根据 Flash 的游戏加载风格,我修改成了实用并且简单的类库!
我们先来看下最终结果的示例演示代码:

</pre><br />
我们需要事先说明的是:场景打包成 unity3d 后缀文件, 其他的打包成 assetbundle 后缀文件! 类库中所有文件如下:
WwwData.cs 文件
using UnityEngine;
using System.Collections;

/// <summary>
/// 加载完成资源存储结构
/// </summary>
public class WwwData
{
/// <summary>
/// 加载路径
/// </summary>
public string path;

/// <summary>
/// 加载类型枚举
/// </summary>
public WwwLoaderTypeEnum loaderTypeEnum;

/// <summary>
/// 加载完成之后的数据
/// </summary>
public WWW www;

/// <summary>
/// 构造函数
/// </summary>
/// <param name="path">Path.</param>
/// <param name="loaderTypeEnum">Loader type enum.</param>
/// <param name="www">Www.</param>
/// <param name="loaderDestroyTypeEnum">Loader destroy type enum.</param>
public WwwData(string path, WwwLoaderTypeEnum loaderTypeEnum, WWW www)
{
this.path = path;
this.loaderTypeEnum = loaderTypeEnum;
this.www = www;
}
}WwwDataManager.cs 文件
using UnityEngine;
using System.Collections.Generic;

/// <summary>
/// 资源管理器
/// </summary>
public class WwwDataManager
{
public static readonly WwwDataManager instance = new WwwDataManager();

/// <summary>
/// 加载缓存数据
/// </summary>
private Dictionary<string, WwwData> dataList;

/// <summary>
/// 所有未被释放的引用
/// </summary>
private IList<AssetBundle> assetList;

/// <summary>
/// 数据总数
/// </summary>
/// <returns>The count.</returns>
public int dataCount()
{
if (this.dataList == null) return 0;
return this.dataList.Keys.Count;
}

/// <summary>
/// 添加数据到缓存
/// </summary>
/// <param name="wwwData">Www data.</param>
public void InsertData(WwwData wwwData)
{
if (wwwData == null) return;
// 如果为空,要创建
if (this.dataList == null) this.dataList = new Dictionary<string, WwwData> ();
this.dataList.Add (wwwData.path, wwwData);
}

/// <summary>
/// 移除数据对象
/// </summary>
/// <param name="path">Path.</param>
public void RemoveData(string path, bool destroy = false)
{
if (this.dataList == null || !this.dataList.ContainsKey (path)) return;

WwwData wwwData = this.dataList [path];
if (wwwData != null)
{
// 释放引用的资源
if(wwwData.www.assetBundle != null)
{
wwwData.www.assetBundle.Unload(false);
}
wwwData.www.Dispose();
wwwData.www = null;
}
this.dataList.Remove (path);

if (destroy) this.Destroy ();
}

/// <summary>
/// 卸载资源
/// </summary>
/// <param name="path">Path.</param>
public void UnloadData(string path)
{
AssetBundle assetBundle = this.GetDataAssetBundle (path);
if (assetBundle != null) assetBundle.Unload (false);
}

/// <summary>
/// 清除对象
/// </summary>
public void Destroy()
{
Resources.UnloadUnusedAssets();
}

/// <summary>
/// 获取字符串
/// </summary>
/// <returns>The data text.</returns>
/// <param name="path">Path.</param>
/// <param name="loaderTypeEnum">Loader type enum.</param>
public string GetDataText(string path)
{
if (this.dataList == null || !this.dataList.ContainsKey(path)) return "";

WwwData wwwData = this.dataList [path];
if (wwwData != null) return wwwData.www.text;

return "";
}

/// <summary>
/// 获取声音
/// </summary>
/// <returns>The data audio clip.</returns>
/// <param name="path">Path.</param>
public AudioClip GetDataAudioClip(string path)
{
if (this.dataList == null || !this.dataList.ContainsKey(path)) return null;

WwwData wwwData = this.dataList [path];
if (wwwData != null) return wwwData.www.audioClip;

return null;
}

/// <summary>
/// 获取 AssetBundle 对象
/// </summary>
/// <returns>The data asset bundle.</returns>
/// <param name="path">Path.</param>
/// <param name="loaderTypeEnum">Loader type enum.</param>
public AssetBundle GetDataAssetBundle(string path)
{
if (this.dataList == null || !this.dataList.ContainsKey(path)) return null;

WwwData wwwData = this.dataList [path];
if (wwwData != null) return wwwData.www.assetBundle;

return null;
}

/// <summary>
/// 获取 Texture2D 对象
/// </summary>
/// <returns>The data texture.</returns>
/// <param name="path">Path.</param>
/// <param name="loaderTypeEnum">Loader type enum.</param>
public Texture2D GetDataTexture(string path)
{
if (this.dataList == null || !this.dataList.ContainsKey(path)) return null;

WwwData wwwData = this.dataList [path];
if (wwwData != null) return wwwData.www.texture;

return null;
}

/// <summary>
/// 加载 GameObject 预设引用
/// </summary>
/// <returns>The game object by prefab name.</returns>
/// <param name="path">Path.</param>
/// <param name="loaderTypeEnum">Loader type enum.</param>
/// <param name="prefabName">Prefab name.</param>
/// <param name="mainAsset">If set to <c>true</c> main asset.</param>
public GameObject CreateGameObjectByPrefabName (string path, string prefabName, bool mainAsset = false, bool unload = true)
{
AssetBundle assetBundle = this.GetDataAssetBundle (path);
if (assetBundle == null) return null;

GameObject prefabObject = null;
if (mainAsset)
{
prefabObject = (GameObject)assetBundle.mainAsset;
} else {
prefabObject = (GameObject)assetBundle.Load (prefabName, typeof(GameObject));
}

// 用完立刻卸载
if (unload)
{
assetBundle.Unload (false);
} else
{
if(this.assetList == null) this.assetList = new List<AssetBundle>();
if(!this.assetList.Contains(assetBundle)) this.assetList.Add(assetBundle);
}

return prefabObject;
}

/// <summary>
/// 加载 Texture2D 预设引用
/// </summary>
/// <returns>The texture by prefab name.</returns>
/// <param name="path">Path.</param>
/// <param name="loaderTypeEnum">Loader type enum.</param>
/// <param name="prefabName">Prefab name.</param>
/// <param name="mainAsset">If set to <c>true</c> main asset.</param>
public Texture2D CreateTextureByPrefabName (string path, string prefabName, bool mainAsset = false, bool unload = true)
{
AssetBundle assetBundle = this.GetDataAssetBundle (path);
if (assetBundle == null) return null;

Texture2D prefabTexture = null;
if (mainAsset)
{
prefabTexture = (Texture2D)assetBundle.mainAsset;
} else {
prefabTexture = (Texture2D)assetBundle.Load (prefabName);
}
// 用完立刻卸载
if (unload)
{
assetBundle.Unload (false);
} else
{
if(this.assetList == null) this.assetList = new List<AssetBundle>();
if(!this.assetList.Contains(assetBundle)) this.assetList.Add(assetBundle);
}

return prefabTexture;
}

/// <summary>
/// 判断是否存在数据
/// </summary>
/// <returns><c>true</c>, if data was existsed, <c>false</c> otherwise.</returns>
/// <param name="path">Path.</param>
public bool ExistsData(string path)
{
if (this.dataList == null) return false;

return this.dataList.ContainsKey (path);
}
}WwwLoaderItem .cs 文件
using UnityEngine;
using System.Collections;

/// <summary>
/// 单个对象加载管理器
/// </summary>
public class WwwLoaderItem : MonoBehaviour
{
// 加载进度
public delegate void DelegateLoaderProgress(string path, float currentValue, float totalValue);
// 加载完成
pu
4000
blic delegate void DelegateLoaderComplete(WWW data);
// 加载出错
public delegate void DelegateLoaderError (string errorText);

// 加载进度
public event DelegateLoaderProgress OnProgress;
// 加载完成
public event DelegateLoaderComplete OnComplete;
// 加载出错
public event DelegateLoaderError OnError;

/// <summary>
/// 加载状态
/// </summary>
private bool progressStatus = false;

/// <summary>
/// 加载对象
/// </summary>
private WWW www;

/// <summary>
/// 调用进度事件
/// </summary>
/// <param name="path">Path.</param>
/// <param name="currentValue">Current value.</param>
/// <param name="totalValue">Total value.</param>
private void InvokeProgress(string path, float currentValue, float totalValue)
{
if (this.OnProgress != null) this.OnProgress (path, currentValue, totalValue);
}
/// <summary>
/// 调用完成事件
/// </summary>
/// <param name="data">Data.</param>
private void InvokeComplete(WWW data)
{
if (this.OnComplete != null) this.OnComplete (data);
}
/// <summary>
/// 调用出错事件
/// </summary>
/// <param name="loaderEnum">Loader enum.</param>
private void InvokeError(string errorText)
{
if (this.OnError != null) this.OnError (errorText);
}

/// <summary>
/// 开始加载
/// </summary>
/// <param name="path">Path.</param>
public void Loader(string path, WwwLoaderTypeEnum loaderTypeEnum, int version)
{
this.progressStatus = false;
this.StartCoroutine (LoaderBegin(path, loaderTypeEnum, version));
}

/// <summary>
/// 开始加载
/// </summary>
/// <returns>The begin.</returns>
/// <param name="path">Path.</param>
private IEnumerator LoaderBegin(string path, WwwLoaderTypeEnum loaderTypeEnum, int version)
{
// 说明,这儿只有 场景(默认是把场景打包成 Unity3D 后缀文件) 使用缓存池加载,因为不用缓存池加载方法,无法使用 Application.LoadLevel 加载场景
// 可能是自己理解的不多,还是本来就应该是这样,这儿可以按照自己的处理方式进行调整
if (loaderTypeEnum == WwwLoaderTypeEnum.UNITY_3D)
{
this.www = WWW.LoadFromCacheOrDownload(path, version);
} else {
this.www = new WWW(path);
}
yield return this.www;

if (!string.IsNullOrEmpty (this.www.error))
{
this.InvokeError (this.www.error);
}
else
{
if (this.www.isDone)
{
this.InvokeComplete (this.www);
}
}
this.StopCoroutine (LoaderBegin(path, loaderTypeEnum, version));
}

/// <summary>
/// 触发加载进度
/// </summary>
void Update()
{
if (this.www != null && !this.progressStatus)
{
if(this.www.progress >= 1) this.progressStatus = true;
this.InvokeProgress (this.www.url, this.www.progress, 1);
}
}

/// <summary>
/// 销毁对象
/// </summary>
public void UnLoader()
{
Destroy (this.gameObject);
}

/// <summary>
/// 销毁自己
/// </summary>
public void UnLoaderThis()
{
Destroy (this);
}
}WwwLoaderManager.cs 文件
using UnityEngine;
using System.Collections.Generic;

/// <summary>
/// 资源加载管理器
/// </summary>
public class WwwLoaderManager
{
public static readonly WwwLoaderManager instance = new WwwLoaderManager();

// 加载进度
public delegate void DelegateLoaderProgress(string path, float currentValue, float totalValue);
// 加载完成
public delegate void DelegateLoaderComplete ();

/// <summary>
/// 加载顺序列表
/// </summary>
private IList<WwwLoaderOrder> orderList;

/// <summary>
/// 当前加载对象
/// </summary>
private WwwLoaderObject wwwLoaderObject;

/// <summary>
/// 当前加载顺序对象
/// </summary>
private WwwLoaderOrder wwwLoaderOrder;

/// <summary>
/// 当前加载路径
/// </summary>
private WwwLoaderPath wwwLoaderPath;

/// <summary>
/// 当前加载状态
/// </summary>
private bool loaderStatus = false;

/// <summary>
/// 加载
/// </summary>
/// <param name="pathList">Path list.</param>
/// <param name="loaderProgress">Loader progress.</param>
/// <param name="loaderComplete">Loader complete.</param>
/// <param name="moduleName">Module name.</param>
public void Loader(IList<WwwLoaderPath> pathList, WwwLoaderManager.DelegateLoaderProgress loaderProgress, WwwLoaderManager.DelegateLoaderComplete loaderComplete, string moduleName)
{
if(this.orderList == null) this.orderList = new List<WwwLoaderOrder>();

WwwLoaderOrder wwwLoaderOrder = this.GetWwwLoaderOrderByOrderName (moduleName);
if (wwwLoaderOrder == null)
{
wwwLoaderOrder = new WwwLoaderOrder (moduleName, pathList, loaderProgress, loaderComplete);
this.orderList.Add (wwwLoaderOrder);
} else {
wwwLoaderOrder.AttachEvent(loaderProgress, loaderComplete);
}

if (this.orderList != null && this.orderList.Count > 0 && !this.loaderStatus)
{
this.LoaderOrder ();
}
}

/// <summary>
/// 加载顺序
/// </summary>
private void LoaderOrder()
{
if (this.orderList.Count > 0)
{
this.loaderStatus = true;
this.wwwLoaderOrder = this.orderList [0];
this.LoaderItem ();
} else {
this.loaderStatus = false;
}
}

/// <summary>
/// 加载对象
/// </summary>
private void LoaderItem()
{
if (this.wwwLoaderOrder != null && this.wwwLoaderOrder.pathList.Count > 0)
{
this.wwwLoaderPath = this.wwwLoaderOrder.pathList[0];
//检查是否在缓存对象中,是否已经加载过
bool existsStatus = WwwDataManager.instance.ExistsData(this.wwwLoaderPath.path);
if(!existsStatus)
{
if(this.wwwLoaderObject == null) this.wwwLoaderObject = new WwwLoaderObject();
this.wwwLoaderObject.Loader(this.wwwLoaderPath.path, this.wwwLoaderPath.loaderTypeEnum, this.wwwLoaderPath.version, OnProgressHandler, OnCompleteHandler, OnErrorHandler);
}else{
this.LoaderOperater(false, null);
}
} else {
if(this.wwwLoaderOrder != null)
{
if(this.wwwLoaderOrder.wwwLoaderOrderEvent != null) this.wwwLoaderOrder.wwwLoaderOrderEvent.InvokeLoaderComplete();
this.orderList.Remove(this.wwwLoaderOrder);
}
this.LoaderOrder();
}
}

/// <summary>
/// 加载进度
/// </summary>
/// <param name="path">Path.</param>
/// <param name="currentValue">Current value.</param>
/// <param name="totalValue">Total value.</param>
private void OnProgressHandler(string path, float currentValue, float totalValue)
{
if (this.wwwLoaderOrder != null && this.wwwLoaderOrder.wwwLoaderOrderEvent != null) this.wwwLoaderOrder.wwwLoaderOrderEvent.InvokeLoaderProgress(path, currentValue, totalValue);
}

/// <summary>
/// 加载完成
/// </summary>
/// <param name="www">Www.</param>
private void OnCompleteHandler(WWW www)
{
this.LoaderOperater (true, www);
}

/// <summary>
/// 加载错误
/// </summary>
/// <param name="errorText">Error text.</param>
private void OnErrorHandler(string errorText)
{
this.LoaderOperater (false, null);
}

/// <summary>
/// 加载数据操作
/// </summary>
/// <param name="operaterType">If set to <c>true</c> operater type.</param>
/// <param name="www">Www.</param>
private void LoaderOperater(bool operaterType, WWW www)
{
if (this.wwwLoaderOrder == null || this.wwwLoaderPath == null) return;

if (operaterType)
{
if(this.wwwLoaderPath.loaderTypeEnum != WwwLoaderTypeEnum.UNITY_3D)
{
WwwData wwwData = new WwwData (this.wwwLoaderPath.path, this.wwwLoaderPath.loaderTypeEnum, www);
WwwDataManager.instance.InsertData(wwwData);
}
}
this.wwwLoaderOrder.pathList.Remove (this.wwwLoaderPath);

if (this.wwwLoaderObject != null) this.wwwLoaderObject.UnLoader (false);

this.LoaderItem ();
}

/// <summary>
/// 根据序列名称检索加载序列
/// </summary>
/// <returns>The www loader order by order name.</returns>
/// <param name="orderName">Order name.</param>
private WwwLoaderOrder GetWwwLoaderOrderByOrderName(string orderName)
{
if (this.orderList == null || this.orderList.Count == 0) return null;

foreach (WwwLoaderOrder wwwLoaderOrder in this.orderList)
{
if(wwwLoaderOrder.orderName == orderName) return wwwLoaderOrder;
}
return null;
}
}WwwLoaderObject.cs 文件
using UnityEngine;
using System.Collections;

/// <summary>
/// 单个对象加载器,可单独使用加载资源
/// 可以使用这个类一个一个的加载资源
/// </summary>
public class WwwLoaderObject
{
/// <summary>
/// 空对象
/// </summary>
private GameObject gameObject;

/// <summary>
/// 加载脚本
/// </summary>
private WwwLoaderItem wwwLoaderItem;

/// <summary>
/// 加载进度
/// </summary>
private WwwLoaderItem.DelegateLoaderProgress loaderProgress;

/// <summary>
/// 加载完成
/// </summary>
private WwwLoaderItem.DelegateLoaderComplete loaderComplete;

/// <summary>
/// 加载错误
/// </summary>
private WwwLoaderItem.DelegateLoaderError loaderError;

/// <summary>
/// 开始加载
/// </summary>
/// <param name="path">Path.</param>
/// <param name="loaderTypeEnum">Loader type enum.</param>
/// <param name="version">Version.</param>
/// <param name="loaderProgress">Loader progress.</param>
/// <param name="loaderComplete">Loader complete.</param>
/// <param name="loaderError">Loader error.</param>
public void Loader(string path, WwwLoaderTypeEnum loaderTypeEnum, int version, WwwLoaderItem.DelegateLoaderProgress loaderProgress, WwwLoaderItem.DelegateLoaderComplete loaderComplete, WwwLoaderItem.DelegateLoaderError loaderError)
{
this.loaderProgress = loaderProgress;
this.loaderComplete = loaderComplete;
this.loaderError = loaderError;

if (this.gameObject == null)
{
this.gameObject = new GameObject ();
this.gameObject.name = "ResourceLoaderManager";
}
this.wwwLoaderItem = this.gameObject.AddComponent<WwwLoaderItem> ();

if(this.wwwLoaderItem == null) return;

this.wwwLoaderItem.OnProgress += this.loaderProgress;
this.wwwLoaderItem.OnError += this.loaderError;
this.wwwLoaderItem.OnComplete += this.loaderComplete;

this.wwwLoaderItem.Loader (path, loaderTypeEnum, version);
}

/// <summary>
/// 销毁对象
/// </summary>
public void UnLoader(bool destory = true)
{
if(this.wwwLoaderItem == null) return;

this.wwwLoaderItem.OnProgress -= this.loaderProgress;
this.wwwLoaderItem.OnError -= this.loaderError;
this.wwwLoaderItem.OnComplete -= this.loaderComplete;
// 销毁自己
this.wwwLoaderItem.UnLoaderThis ();
// 销毁对象
if (destory) this.wwwLoaderItem.UnLoader ();
}
}WwwLoaderOrder.cs 文件
using UnityEngine;
using System.Collections.Generic;

/// <summary>
/// 顺序加载管理器
/// </summary>
public class WwwLoaderOrder
{
/// <summary>
/// 队列名称
/// </summary>
public string orderName;

/// <summary>
/// 路径列表
/// </summary>
public IList<WwwLoaderPath> pathList;

/// <summary>
/// 队列事件
/// </summary>
public WwwLoaderOrderEvent wwwLoaderOrderEvent;

/// <summary>
/// 构造函数
/// </summary>
/// <param name="orderName">Order name.</param>
/// <param name="pathList">Path list.</param>
/// <param name="loaderProgress">Loader progress.</param>
/// <param name="loaderComplete">Loader complete.</param>
public WwwLoaderOrder(string orderName, IList<WwwLoaderPath> pathList, WwwLoaderManager.DelegateLoaderProgress loaderProgress, WwwLoaderManager.DelegateLoaderComplete loaderComplete)
{
this.orderName = orderName;
this.pathList = pathList;

this.AttachEvent (loaderProgress, loaderComplete);
}

/// <summary>
/// 附加事件
/// </summary>
/// <param name="loaderProgress">Loader progress.</param>
/// <param name="loaderComplete">Loader complete.</param>
public void AttachEvent(WwwLoaderManager.DelegateLoaderProgress loaderProgress, WwwLoaderManager.DelegateLoaderComplete loaderComplete)
{
if (this.wwwLoaderOrderEvent == null)
{
this.wwwLoaderOrderEvent = new WwwLoaderOrderEvent();
}

if(loaderProgress != null) this.wwwLoaderOrderEvent.OnLoaderProgress += loaderProgress;
if(loaderComplete != null) this.wwwLoaderOrderEvent.OnLoaderComplete += loaderComplete;
}

/// <summary>
/// 移除事件
/// </summary>
/// <param name="loaderProgress">Loader progress.</param>
/// <param name="loaderComplete">Loader complete.</param>
public void RemoveEvent(WwwLoaderManager.DelegateLoaderProgress loaderProgress, WwwLoaderManager.DelegateLoaderComplete loaderComplete)
{
if (this.wwwLoaderOrderEvent == null) return;

if(loaderProgress != null) this.wwwLoaderOrderEvent.OnLoaderProgress -= loaderProgress;
if(loaderComplete != null) this.wwwLoaderOrderEvent.OnLoaderComplete -= loaderComplete;
}
}WwwLoaderOrderEvent.cs 文件
using UnityEngine;
using System.Collections;

/// <summary>
/// 顺序加载管理器事件
/// </summary>
public class WwwLoaderOrderEvent
{
// 加载进度委托
public WwwLoaderManager.DelegateLoaderProgress OnLoaderProgress;
// 加载完成委托
public WwwLoaderManager.DelegateLoaderComplete OnLoaderComplete;

/// <summary>
/// 触发进度委托函数
/// </summary>
/// <param name="path">Path.</param>
/// <param name="currentValue">Current value.</param>
/// <param name="totalValue">Total value.</param>
public void InvokeLoaderProgress(string path, float currentValue, float totalValue)
{
if (this.OnLoaderProgress != null) this.OnLoaderProgress (path, currentValue, totalValue);
}

/// <summary>
/// 触发完成委托函数
/// </summary>
public void InvokeLoaderComplete()
{
if (this.OnLoaderComplete != null) this.OnLoaderComplete ();
}
}WwwLoaderPath.cs 文件
using UnityEngine;
using System.Collections;

/// <summary>
/// 加载路径结构
/// </summary>
public class WwwLoaderPath
{
/// <summary>
/// 加载路径
/// </summary>
public string path;

/// <summary>
/// 资源版本号
/// </summary>
public int version;

/// <summary>
/// 资源类别
/// </summary>
public WwwLoaderTypeEnum loaderTypeEnum;

/// <summary>
/// 构造函数
/// </summary>
/// <param name="path">Path.</param>
/// <param name="version">Version.</param>
/// <param name="loaderTypeEnum">Loader type enum.</param>
public WwwLoaderPath(string path, int version, WwwLoaderTypeEnum loaderTypeEnum)
{
this.path = path;
this.version = version;
this.loaderTypeEnum = loaderTypeEnum;
}
}WwwLoaderTypeEnum.cs 文件
using UnityEngine;
using System.Collections;

/// <summary>
/// 加载资源类型枚举
/// </summary>
public enum WwwLoaderTypeEnum
{
TEXT = 1, // 文本
TEXTURE = 2, //贴图
AUDIO = 3, // 声音
MOVIE = 4, // 视频
ASSET_BUNDLE = 5, // 资源
UNITY_3D = 6 // 场景
}资源下载地址:点击下载
本文永久地址:http://www.omuying.com/article/23.aspx,【文章转载请注明出处!】
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: