using System.Collections; using System.Collections.Generic; using UnityEngine; using System.IO; public class AssetBundleMgr { public AssetBundleMgr() { m_bundles = new Dictionary(); m_assets = new Dictionary(); } public void PreloadAssetBundles() { #if UNITY_EDITOR // Nothing #else m_normalCfgBundle = LoadAssetBundle("normal_cfg.bundle"); #endif } public Object LoadAsset(string uri) { System.Type t = GetAssetType(uri); if (m_assets.ContainsKey(uri)) return m_assets[uri]; Object obj = null; #if UNITY_EDITOR obj = UnityEditor.AssetDatabase.LoadAssetAtPath("Assets/GameRes/" + uri, t); #else // resources.bytes的第一级目录为AssetBundle var abName = uri.Substring(0, uri.IndexOf("/")).ToLower() + ".bundle"; var fname = Path.GetFileName(uri); AssetBundle ab = null; if (File.Exists(updatePath + "/" + fname)) { // 热更的资源,是一个独立的AssetBundle文件,以fname为文件名 ab = LoadAssetBundle(fname); } else { ab = LoadAssetBundle(abName); } if (null != ab) { var assetName = fname.Substring(0, fname.IndexOf(".")); obj = ab.LoadAsset(assetName); GameLogger.LogGreen("Load Asset From AssetBundle: assetName: " + assetName); } #endif if (null != obj) { m_assets[uri] = obj; } return obj; } public AssetBundle LoadAssetBundle(string abName) { if (m_bundles.ContainsKey(abName)) return m_bundles[abName]; AssetBundle bundle = null; if (File.Exists(updatePath + "/" + abName)) { // 优先从update目录(热更新目录)中查找资源 bundle = AssetBundle.LoadFromFile(updatePath + abName); } else if (File.Exists(extPath + "/" + abName)) { // 从拓展包目录加载资源 bundle = AssetBundle.LoadFromFile(extPath + abName); } else { bundle = AssetBundle.LoadFromFile(internalPath + abName); } /* // 如果对AssetBundle做了加密处理,则需要使用流式读取,进行解密后再通过AssetBundle.LoadFromMemory加载AssetBundle byte[] stream = null; stream = File.ReadAllBytes(path + "/" + abName); // TOOD 对stream做解密 var bundle = AssetBundle.LoadFromMemory(stream); */ if (null != bundle) { m_bundles[abName] = bundle; GameLogger.Log("LoadAssetBundle Ok, abName: " + abName); } return bundle; } protected System.Type GetAssetType(string uri) { if (uri.EndsWith(".prefab")) { return typeof(GameObject); } else if (uri.EndsWith(".ogg") || uri.EndsWith(".wav")) { return typeof(AudioClip); } else if (uri.EndsWith(".spriteatlas")) { return typeof(UnityEngine.U2D.SpriteAtlas); } else if (uri.EndsWith(".mat")) { return typeof(Material); } else if (uri.EndsWith(".anim")) { return typeof(AnimationClip); } return typeof(AssetBundle); } /// /// 热更新目录 /// /// public string updatePath { get { return Application.persistentDataPath + "/update/"; } } /// /// 拓展包目录 /// /// public string extPath { get { return Application.persistentDataPath + "/ext/"; } } /// /// 内部资源目录 /// 获取内部资源路径,对应streamingAssetsPath, /// 一般情况,streamingAssetsPath目录中的资源只能用WWW异步加载,但是AssetBundle提供了LoadFromFile方法可以直接同步加载 /// 在Android中,Application.streamingAssetsPath会在前面加上"jar:file://" /// 所以不直接使用Application.streamingAssetsPath,而使用Application.dataPath + "!assets“ /// /// public string internalPath { get { #if UNITY_ANDROID return Application.dataPath + "!assets/res/"; #else return Application.streamingAssetsPath + "/res/"; #endif } } /// /// 常规配置AssetBundle (C# 使用的xml配置表) /// public AssetBundle m_normalCfgBundle; private Dictionary m_assets; private Dictionary m_bundles; private static AssetBundleMgr s_instance; public static AssetBundleMgr instance { get { if (null == s_instance) s_instance = new AssetBundleMgr(); return s_instance; } } }