using System.Collections; using System.Collections.Generic; using UnityEngine; namespace SFramework { public class SResourceManager { private static AssetBundleManifest _mainAssetBundleManifest = null; private static Dictionary _loadedAssetBundle = new Dictionary(); public static string TestCall(string value) { Debug.Log("SFramework.SResourceManager.TestCall -> " + value); return "TestCall Return Value."; } public static UnityEngine.Object LoadResource(string resourcePath) { UnityEngine.Object targetObject = null; resourcePath = resourcePath.ToLower(); #pragma warning disable 0162 // Editor Direct Read Res if (Application.isEditor && !SFrameworkDef.isLoadAssetsBundleOnEditor) { string resFinalPath = ""; #if UNITY_EDITOR resFinalPath = "Assets/" + SFrameworkDef.ResourceDir + "/" + resourcePath; targetObject = UnityEditor.AssetDatabase.LoadAssetAtPath(resFinalPath, typeof(UnityEngine.Object)); Debug.Assert(targetObject != null); #endif return targetObject; } #pragma warning restore 0162 // Editor or non-Editor Read AssetsBundle else { // Check Main AssetBundleManifest. if (_mainAssetBundleManifest == null) { LoadMainAssetBundleManifest(); } string abExtName = SFrameworkDef.AssetsBundleExtName; targetObject = LoadOneAssetBundle(resourcePath + abExtName); // Disable it on 20181023 by SunXun. Because targeetObject == null. If the assetbundle.isStreamedSceneAssetBundle == true. // Debug.Assert(targetObject != null); return targetObject; } } private static void LoadMainAssetBundleManifest() { string mainManifestPath = ""; string platformName = SPlatformInfo.GetBuildPlatformName(); string persistentPath = Application.persistentDataPath + "/Bundles/" + platformName + "/" + platformName; string streamingPath = Application.streamingAssetsPath + "/Bundles/" + platformName + "/" + platformName; // Process Special Android Path. if (platformName == "Android" && !Application.isEditor) { streamingPath = Application.dataPath + "!assets/Bundles/" + platformName + "/" + platformName; mainManifestPath = streamingPath; } if (System.IO.File.Exists(streamingPath)) mainManifestPath = streamingPath; if (System.IO.File.Exists(persistentPath)) mainManifestPath = persistentPath; if (string.IsNullOrEmpty(mainManifestPath)) { Debug.LogError(string.Format("LoadMainAssetBundleManifest Failed ! File:{0} Is Not Existed!", mainManifestPath)); return; } Debug.Log("LoadMainAssetBundleManifest -> mainManifestPath -> " + mainManifestPath); AssetBundle manifestAB = AssetBundle.LoadFromFile(mainManifestPath); Debug.Assert(mainManifestPath != null); _mainAssetBundleManifest = manifestAB.LoadAsset("AssetBundleManifest") as AssetBundleManifest; Debug.Assert(_mainAssetBundleManifest != null); Debug.Log("LoadMainAssetBundleManifest Success!"); } private static UnityEngine.Object LoadOneAssetBundle(string assetBundleFullName) { Debug.Assert(_mainAssetBundleManifest != null); UnityEngine.Object targetObject; string resourcePath = ""; string platformName = SPlatformInfo.GetBuildPlatformName(); string persistentPath = Application.persistentDataPath + "/Bundles/" + platformName + "/" + assetBundleFullName; string streamingPath = Application.streamingAssetsPath + "/Bundles/" + platformName + "/" + assetBundleFullName; string assetName = GetAssetNameByAssetBundleFullName(assetBundleFullName); // Process Loaded Asset Bundle. if (_loadedAssetBundle.ContainsKey(assetBundleFullName)) { AssetBundle loadedAB = _loadedAssetBundle[assetBundleFullName]; Debug.Assert(loadedAB != null); targetObject = loadedAB.LoadAsset(assetName); Debug.Assert(targetObject != null); Debug.Log(string.Format("LoadOneAssetBundle -> Load By Cache AsetName:{0} From:{1}", assetName, assetBundleFullName)); return targetObject; } // Process Special Android Path. if (platformName == "Android" && !Application.isEditor) { streamingPath = Application.dataPath + "!assets/Bundles/" + platformName + "/" + assetBundleFullName; resourcePath = streamingPath; } // For Editor Link. if (System.IO.File.Exists(streamingPath)) resourcePath = streamingPath; if (System.IO.File.Exists(persistentPath)) resourcePath = persistentPath; if (string.IsNullOrEmpty(resourcePath)) { Debug.LogError(string.Format("LoadOneAssetBundle Failed ! File:{0} Is Not Existed!", assetBundleFullName)); return null; } //Debug.Log("LoadOneAssetBundle -> resourcePath -> " + resourcePath); // Load All Dependencies string[] dependenciesArray = _mainAssetBundleManifest.GetAllDependencies(assetBundleFullName); for (var depIndex = 0; depIndex < dependenciesArray.Length; depIndex++) LoadOneAssetBundle(dependenciesArray[depIndex]); // Load AssetBundle AssetBundle resourceAB = AssetBundle.LoadFromFile(resourcePath); Debug.Assert(resourceAB != null); if (resourceAB.isStreamedSceneAssetBundle) { // isStreamedSceneAssetBundle Can't Be LoadAsset. // just can load like below. // string[] scenePath = resourceAB.GetAllScenePaths(); // string sceneName = System.IO.Path.GetFileNameWithoutExtension(scenePath[0]); // UnityEngine.SceneManagement.Scene targetScene = UnityEngine.SceneManagement.SceneManager.GetSceneByName(sceneName); // UnityEngine.SceneManagement.SceneManager.LoadScene(sceneName); // targetObject = targetScene as UnityEngine.Object; targetObject = null; } else { targetObject = resourceAB.LoadAsset(assetName); Debug.Assert(targetObject != null); } _loadedAssetBundle.Add(assetBundleFullName, resourceAB); Debug.Log(string.Format("LoadOneAssetBundle -> Load By File AssetName:{0} From:{1}", assetName, assetBundleFullName)); return targetObject; } private static string GetAssetNameByAssetBundleFullName(string assetBundleFullName) { string[] splitArray = assetBundleFullName.Split('/'); string splitString = splitArray[splitArray.Length - 1]; int extNameLengh = SFrameworkDef.AssetsBundleExtName.Length; string finalString = splitString.Substring(0, splitString.Length - extNameLengh); return finalString; } private static string GetAssetNameByAssetBundleFullNameWithExt(string assetBundleFullName) { string[] splitArray = assetBundleFullName.Split('/'); string splitString = splitArray[splitArray.Length - 1]; string finalString = splitString; return finalString; } public static SFramework.SVersionInfo GetLocalVersionInfo() { var platformName = SPlatformInfo.GetBuildPlatformName(); string persistentPath = Application.persistentDataPath + "/Bundles/" + platformName + "/" + SFrameworkDef.VersionFileName; string streamingPath = Application.streamingAssetsPath + "/Bundles/" + platformName + "/" + SFrameworkDef.VersionFileName; string versionFilePath = ""; bool canLoadFromFileDirectly = false; // Process Special Android Real Machine Path. if (platformName == "Android" && !Application.isEditor) { streamingPath = "jar:file://" + Application.dataPath + "!assets/Bundles/" + platformName + "/" + SFrameworkDef.VersionFileName; versionFilePath = streamingPath; canLoadFromFileDirectly = false; } // For Editor Link. if (System.IO.File.Exists(streamingPath)) { versionFilePath = streamingPath; canLoadFromFileDirectly = true; } Debug.Log("persistentPath -> " + persistentPath); if (System.IO.File.Exists(persistentPath)) { versionFilePath = persistentPath; canLoadFromFileDirectly = true; } if (string.IsNullOrEmpty(versionFilePath)) { Debug.LogError(string.Format("GetLocalVersionInfo Failed ! File:{0} Is Not Existed!", versionFilePath)); return null; } Debug.Log("GetLocalVersionInfo -> File Path -> " + versionFilePath); string versionInfo = ""; if (canLoadFromFileDirectly) { versionInfo = System.IO.File.ReadAllText(versionFilePath); } else { UnityEngine.Networking.UnityWebRequest versionFileLoader = UnityEngine.Networking.UnityWebRequest.Get(versionFilePath); versionFileLoader.timeout = 3; versionFileLoader.SendWebRequest(); while (!versionFileLoader.isDone) { // just wait. } //if (versionFileLoader.isNetworkError || versionFileLoader.isHttpError) if (versionFileLoader.result == UnityEngine.Networking.UnityWebRequest.Result.ConnectionError || versionFileLoader.result == UnityEngine.Networking.UnityWebRequest.Result.ProtocolError) { Debug.LogError("GetLocalVersionInfo -> versionFileLoader error ->" + versionFileLoader.error); return null; } versionInfo = versionFileLoader.downloadHandler.text; } SVersionInfo localVersionInfo = LitJson.JsonMapper.ToObject(versionInfo); Debug.Assert(localVersionInfo != null); return localVersionInfo; } public static void TryDeleteAssetBundle(string assetBundleName) { // Here the assetBundleName include ext name , Like -> "prefabs/xxxx.prefab.s" string platformName = SPlatformInfo.GetBuildPlatformName(); string filePath = Application.persistentDataPath + "/Bundles/" + platformName + "/" + assetBundleName; string fileManifesetPath = filePath + ".manifest"; // Delete AssetBundle File. if (System.IO.File.Exists(filePath)) { System.IO.File.Delete(filePath); Debug.Log(string.Format("TryDeleteAssetBundle -> Delete File:{0} Path:{1}", assetBundleName, filePath)); } // Delete AssetBundle.manifest File. if (System.IO.File.Exists(fileManifesetPath)) { System.IO.File.Delete(fileManifesetPath); Debug.Log(string.Format("TryDeleteAssetBundle -> Delete File:{0} Path:{1}", assetBundleName + ".manifest", filePath)); } } public static void SaveAssetBundle(string assetBundleName, byte[] assetBundleData) { string platformName = SPlatformInfo.GetBuildPlatformName(); string abFullPathWithName = Application.persistentDataPath + "/Bundles/" + platformName + "/" + assetBundleName; string abFullPath = SToolFunction.GetAssetBundleFullPath(abFullPathWithName); // Debug.Log("abFullPathWithName -> " + abFullPathWithName); // Debug.Log("abFullPath -> " + abFullPath); SToolFunction.MakeSurePathExisted(abFullPath); System.IO.File.WriteAllBytes(abFullPathWithName, assetBundleData); // Below is wrong. file size error. // System.IO.StreamWriter abWriter = new System.IO.StreamWriter(abFullPathWithName); // abWriter.Write(assetBundleData); // abWriter.Close(); // abWriter.Dispose(); Debug.Log(string.Format( "SResourceManager -> SaveAssetBundle abName:{0} abPath:{1}", assetBundleName, abFullPathWithName )); } public static void SaveRemoteVersion(SVersionInfo remoteVersion) { string platformName = SPlatformInfo.GetBuildPlatformName(); string versionPath = Application.persistentDataPath + "/Bundles/" + platformName + "/"; string jsonInfo = LitJson.JsonMapper.ToJson(remoteVersion); SToolFunction.MakeSurePathExisted(versionPath); versionPath += SFrameworkDef.VersionFileName; System.IO.StreamWriter versionWriter = new System.IO.StreamWriter(versionPath); versionWriter.Write(jsonInfo); versionWriter.Close(); versionWriter.Dispose(); Debug.Log(string.Format( "SResourceManager -> SaveRemoteVersion -> SavePath:{0} VersionInfo:{1}", versionPath, jsonInfo )); } } }