网上演练贵港万达广场(人员密集)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

529 lines
18 KiB

#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using System.IO;
// 已加载的assetBundle引用计数
public class LoadedAssetBundle
{
public AssetBundle m_AssetBundle;
public int m_ReferencedCount;
public LoadedAssetBundle(AssetBundle assetBundle)
{
m_AssetBundle = assetBundle;
m_ReferencedCount = 1;
}
}
// AB管理类
public class AssetBundleManager : Singleton<AssetBundleManager>
{
static string m_BaseDownloadingURL = "";
static string[] m_Variants = { };
static AssetBundleManifest m_AssetBundleManifest = null;
#if UNITY_EDITOR
static int m_SimulateAssetBundleInEditor = -1;
const string kSimulateAssetBundles = "SimulateAssetBundles";
#endif
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; }
}
//
public static string[] Variants
{
get { return m_Variants; }
set { m_Variants = value; }
}
// AssetBundleManifest
public static AssetBundleManifest AssetBundleManifestObject
{
set { m_AssetBundleManifest = value; }
}
const string AssetBundlesPath = "/AssetBundles/";
//初始化
protected IEnumerator Initialize()
{
#if UNITY_EDITOR
//Debug.Log("当前模式:" + (SimulateAssetBundleInEditor ? "模拟模式" : "正常模式"));
#endif
string platformFolderForAssetBundles =
#if UNITY_EDITOR
GetPlatformFolderForAssetBundles(EditorUserBuildSettings.activeBuildTarget);
#else
GetPlatformFolderForAssetBundles(Application.platform);
#endif
//下载路径
string relativePath = GetRelativePath();
BaseDownloadingURL = relativePath + AssetBundlesPath + platformFolderForAssetBundles + "/";
var request = Initialize(platformFolderForAssetBundles);
if (request != null)
{
yield return StartCoroutine(request);
}
Initializing = false;
}
// 真实路径
public string GetRelativePath()
{
if (Application.isEditor)
//return "file://" + System.Environment.CurrentDirectory.Replace("\\", "/");
return "file://" + Application.streamingAssetsPath;
//else if (Application.isWebPlayer)
// return Path.GetDirectoryName(Application.absoluteURL).Replace("\\", "/") + "/StreamingAssets";
else if (Application.isMobilePlatform || Application.isConsolePlatform)
return Application.streamingAssetsPath;
else
return "file://" + Application.streamingAssetsPath;
}
#if UNITY_EDITOR
public static string GetPlatformFolderForAssetBundles(BuildTarget target)
{
switch (target)
{
case BuildTarget.Android:
return "Android";
case BuildTarget.iOS:
return "iOS";
case BuildTarget.WebGL:
return "WebGL";
case BuildTarget.StandaloneWindows:
case BuildTarget.StandaloneWindows64:
return "Windows";
case BuildTarget.StandaloneOSXIntel:
case BuildTarget.StandaloneOSXIntel64:
case BuildTarget.StandaloneOSX:
return "OSX";
default:
return null;
}
}
#endif
static string GetPlatformFolderForAssetBundles(RuntimePlatform platform)
{
switch (platform)
{
case RuntimePlatform.Android:
return "Android";
case RuntimePlatform.IPhonePlayer:
return "iOS";
case RuntimePlatform.WebGLPlayer:
return "WebGL";
case RuntimePlatform.WindowsPlayer:
return "Windows";
case RuntimePlatform.OSXPlayer:
return "OSX";
default:
return null;
}
}
//IEnumerator Start()
//{
// yield return StartCoroutine(Initialize());
//}
public bool Initializing = false;
public IEnumerator Load<T>(string assetBundleName, string assetName, Action<T> callback)
where T : UnityEngine.Object
{
while (Initializing)
{
yield return new WaitForEndOfFrame();
}
if (m_AssetBundleManifest == null)
{
//Debug.Log("未初始化!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
Initializing = true;
yield return StartCoroutine(Initialize());
}
//Debug.Log(string.Format("在第{0}帧开始加载{1}", Time.frameCount, assetName));
// 从AB中加载资源
AssetBundleLoadAssetOperation request = LoadAssetAsync(assetBundleName, assetName, typeof(T));
if (request == null)
yield break;
yield return StartCoroutine(request);
// 获取资源T
T asset = request.GetAsset<T>();
//Debug.Log(string.Format("加载{0}在第{1}帧时{2}", assetName, Time.frameCount, (asset == null ? "失败" : "成功")));
if (asset != null)
{
callback(asset);
//添加到资源缓存池
ResourceManager.AddAsset(asset.name, asset);
UnloadAssetBundle(assetBundleName);
}
}
//protected IEnumerator LoadLevel(string assetBundleName, string levelName, bool isAdditive)
//{
// Debug.Log("Start to load scene " + levelName + " at frame " + Time.frameCount);
// // Load level from assetBundle.
// AssetBundleLoadOperation request = AssetBundleManager.LoadLevelAsync(assetBundleName, levelName, isAdditive);
// if (request == null)
// yield break;
// yield return StartCoroutine(request);
// // This log will only be output when loading level additively.
// Debug.Log("Finish loading scene " + levelName + " at frame " + Time.frameCount);
//}
#if UNITY_EDITOR
// 是否要在编辑器中模拟assetbundle,而不实际构建它们
public static bool SimulateAssetBundleInEditor
{
get
{
if (m_SimulateAssetBundleInEditor == -1)
m_SimulateAssetBundleInEditor = EditorPrefs.GetBool(kSimulateAssetBundles, true) ? 1 : 0;
return m_SimulateAssetBundleInEditor != 0;
}
set
{
int newValue = value ? 1 : 0;
if (newValue != m_SimulateAssetBundleInEditor)
{
m_SimulateAssetBundleInEditor = newValue;
EditorPrefs.SetBool(kSimulateAssetBundles, value);
}
}
}
#endif
// 获取已加载的AssetBundle,只在成功下载所有依赖项时返回vaild对象。
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;
}
// Load AssetBundleManifest.
static public AssetBundleLoadManifestOperation Initialize(string manifestAssetBundleName)
{
#if UNITY_EDITOR
// If we're in Editor simulation mode, we don't need the manifest assetBundle.
if (SimulateAssetBundleInEditor)
return null;
#endif
LoadAssetBundle(manifestAssetBundleName, true);
var operation = new AssetBundleLoadManifestOperation(manifestAssetBundleName, "AssetBundleManifest", typeof(AssetBundleManifest));
m_InProgressOperations.Add(operation);
return operation;
}
// Load AssetBundle and its dependencies.
static protected void LoadAssetBundle(string assetBundleName, bool isLoadingAssetBundleManifest = false)
{
#if UNITY_EDITOR
// If we're in Editor simulation mode, we don't have to really load the assetBundle and its dependencies.
if (SimulateAssetBundleInEditor)
return;
#endif
if (!isLoadingAssetBundleManifest)
assetBundleName = RemapVariantName(assetBundleName);
// Check if the assetBundle has already been processed.
bool isAlreadyProcessed = LoadAssetBundleInternal(assetBundleName, isLoadingAssetBundleManifest);
// Load dependencies.
if (!isAlreadyProcessed && !isLoadingAssetBundleManifest)
LoadDependencies(assetBundleName);
}
// Remaps the asset bundle name to the best fitting asset bundle variant.
static protected string RemapVariantName(string assetBundleName)
{
string[] bundlesWithVariant = m_AssetBundleManifest.GetAllAssetBundlesWithVariant();
// If the asset bundle doesn't have variant, simply return.
if (System.Array.IndexOf(bundlesWithVariant, assetBundleName) < 0)
return assetBundleName;
string[] split = assetBundleName.Split('.');
int bestFit = int.MaxValue;
int bestFitIndex = -1;
// Loop all the assetBundles with variant to find the best fit variant assetBundle.
for (int i = 0; i < bundlesWithVariant.Length; i++)
{
string[] curSplit = bundlesWithVariant[i].Split('.');
if (curSplit[0] != split[0])
continue;
int found = System.Array.IndexOf(m_Variants, curSplit[1]);
if (found != -1 && found < bestFit)
{
bestFit = found;
bestFitIndex = i;
}
}
if (bestFitIndex != -1)
return bundlesWithVariant[bestFitIndex];
else
return assetBundleName;
}
// Where we actuall call WWW to download the assetBundle.
static protected bool LoadAssetBundleInternal(string assetBundleName, bool isLoadingAssetBundleManifest)
{
// 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;
// For manifest assetbundle, always download it as we don't have hash for it.
if (isLoadingAssetBundleManifest)
download = new WWW(url);
else
download = WWW.LoadFromCacheOrDownload(url, m_AssetBundleManifest.GetAssetBundleHash(assetBundleName), 0);
m_DownloadingWWWs.Add(assetBundleName, download);
return false;
}
// Where we get all the dependencies and load them all.
static protected void LoadDependencies(string assetBundleName)
{
if (m_AssetBundleManifest == null)
{
Debug.LogError("Please initialize AssetBundleManifest by calling AssetBundleManager.Initialize()");
return;
}
// Get dependecies from the AssetBundleManifest object..
string[] dependencies = m_AssetBundleManifest.GetAllDependencies(assetBundleName);
if (dependencies.Length == 0)
return;
for (int i = 0; i < dependencies.Length; i++)
dependencies[i] = RemapVariantName(dependencies[i]);
// Record and load all dependencies.
m_Dependencies.Add(assetBundleName, dependencies);
for (int i = 0; i < dependencies.Length; i++)
LoadAssetBundleInternal(dependencies[i], false);
}
// Unload assetbundle and its dependencies.
static public void UnloadAssetBundle(string assetBundleName)
{
#if UNITY_EDITOR
// If we're in Editor simulation mode, we don't have to load the manifest assetBundle.
if (SimulateAssetBundleInEditor)
return;
#endif
//Debug.Log(m_LoadedAssetBundles.Count + " assetbundle(s) in memory before unloading " + assetBundleName);
UnloadAssetBundleInternal(assetBundleName);
UnloadDependencies(assetBundleName);
//Debug.Log(m_LoadedAssetBundles.Count + " assetbundle(s) in memory after unloading " + assetBundleName);
}
static protected void UnloadDependencies(string assetBundleName)
{
string[] dependencies = null;
if (!m_Dependencies.TryGetValue(assetBundleName, out dependencies))
return;
// Loop dependencies.
foreach (var dependency in dependencies)
{
UnloadAssetBundleInternal(dependency);
}
m_Dependencies.Remove(assetBundleName);
}
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);
//Debug.Log("AssetBundle " + assetBundleName + " has been unloaded successfully");
}
}
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, download.error);
keysToRemove.Add(keyValue.Key);
continue;
}
// If downloading succeeds.
if (download.isDone)
{
//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++;
}
}
// Load asset from the given assetBundle.
static public AssetBundleLoadAssetOperation LoadAssetAsync(string assetBundleName, string assetName, System.Type type)
{
AssetBundleLoadAssetOperation operation = null;
#if UNITY_EDITOR
if (SimulateAssetBundleInEditor)
{
string[] assetPaths = AssetDatabase.GetAssetPathsFromAssetBundleAndAssetName(assetBundleName, assetName);
if (assetPaths.Length == 0)
{
Debug.LogError("There is no asset with name \"" + assetName + "\" in " + assetBundleName);
return null;
}
// 根据类型从AssetDatabase中读取资源
UnityEngine.Object target = AssetDatabase.LoadAssetAtPath(assetPaths[0], type);
// 加载
operation = new AssetBundleLoadAssetOperationSimulation(target);
}
else
#endif
{
LoadAssetBundle(assetBundleName);
operation = new AssetBundleLoadAssetOperationFull(assetBundleName, assetName, type);
m_InProgressOperations.Add(operation);
}
return operation;
}
// // Load level from the given assetBundle.
// static public AssetBundleLoadOperation LoadLevelAsync(string assetBundleName, string levelName, bool isAdditive)
// {
// AssetBundleLoadOperation operation = null;
//#if UNITY_EDITOR
// if (SimulateAssetBundleInEditor)
// {
// string[] levelPaths = AssetDatabase.GetAssetPathsFromAssetBundleAndAssetName(assetBundleName, levelName);
// if (levelPaths.Length == 0)
// {
// ///@TODO: The error needs to differentiate that an asset bundle name doesn't exist
// // from that there right scene does not exist in the asset bundle...
// Debug.LogError("There is no scene with name \"" + levelName + "\" in " + assetBundleName);
// return null;
// }
// if (isAdditive)
// EditorApplication.LoadLevelAdditiveInPlayMode(levelPaths[0]);
// else
// EditorApplication.LoadLevelInPlayMode(levelPaths[0]);
// operation = new AssetBundleLoadLevelSimulationOperation();
// }
// else
//#endif
// {
// LoadAssetBundle(assetBundleName);
// operation = new AssetBundleLoadLevelOperation(assetBundleName, levelName, isAdditive);
// m_InProgressOperations.Add(operation);
// }
// return operation;
// }
}