using System; using System.Collections; using System.Collections.Generic; using System.Linq; using Thousandto.Code.Center; using Thousandto.Core.Asset; using Thousandto.Core.Base; using Thousandto.Core.Support; using UnityEngine; using PathUtils = UnityEngine.Gonbest.MagicCube.PathUtils; using CoroutinePool = UnityEngine.Gonbest.MagicCube.CoroutinePool; using StringUtils = UnityEngine.Gonbest.MagicCube.StringUtils; using FLogger = UnityEngine.Gonbest.MagicCube.FLogger; using UnityEngine.Gonbest.MagicCube; namespace Thousandto.Code.Logic { /// /// 资源预加载器 /// public class AssetPreLoader { #region //变量列表 //总文件 private int _totalCount = 0; //已加载文件 private int _loadedCount = 0; //进度处理回调 private Action _OnProgressHandler; //进度完成回调 private Action _OnFinishedHandler; //当前任务类型 private Coroutine _currentTask = null; //所有的字符串 private string _allChars = string.Empty; //路径列表 private List _pathList = null; #endregion #region// 属性 public List PathList { get { return _pathList; } set { _pathList = value; } } public string AllChars { get { return _allChars; } set { _allChars = value; } } public Action OnFinishedHandler { get { return _OnFinishedHandler; } set { _OnFinishedHandler = value; } } public Action OnProgressHandler { get { return _OnProgressHandler; } set { _OnProgressHandler = value; } } public int LoadedCount { get { return _loadedCount; } } public int TotalCount { get { return _totalCount; } } #endregion //构造函数 public AssetPreLoader() { _pathList = null; _OnProgressHandler = null; _OnFinishedHandler = null; } //构造函数 public AssetPreLoader(List pathList, Action onProgress, Action onFinished) { _pathList = pathList; _OnProgressHandler = onProgress; _OnFinishedHandler = onFinished; } //开始预加载资源 public bool Start(bool forceStart = false) { if (_pathList != null && _pathList.Count > 0) { //如果是强制启动的话 if (forceStart && _currentTask != null) { CoroutinePool.StopTask(_currentTask); _currentTask = null; } if (_currentTask == null) { Debug.Log("添加预加载任务.需要被预加载的资源数量为:" + _pathList.Count + " StartTime:" + Time.realtimeSinceStartup); _currentTask = CoroutinePool.AddTask(PreLoadList(_pathList)); return true; } return false; } else { _totalCount = 0; _loadedCount = 0; OnAssetLoaded(true); } return true; } //预加载一群 private IEnumerator PreLoadList(List pathList) { _totalCount = pathList.Count; _loadedCount = 0; for (int i = 0; i < _totalCount; i++) { PreLoadOne((PreloadAssetTypeCode)pathList[i].Type, pathList[i].AssetName); yield return null; } _currentTask = null; } //预加载一个 private void PreLoadOne(PreloadAssetTypeCode assetType, string assetName) { switch (assetType) { case PreloadAssetTypeCode.Scene: if (PathUtils.IsStreaming()) { var path = StringUtils.CombineString(AssetConstDefine.PathScene, assetName, AssetConstDefine.ExtUnity); path = AssetUtils.MakeFileNameToLower(PathUtils.GetResourcePath((System.IO.Path.ChangeExtension(path, AssetConstDefine.ExtUnity3d)))); bool isExist = false; Update.Manager.UpdateManager.Instance.IsFileValid(path, out isExist); if (!isExist) { FLogger.LogTime(string.Format("场景文件不存在---开始预加载场景:{0}",assetName)); GameCenter.CacheSceneSystem.PreLoadSceneForCache(assetName); } } OnAssetLoaded(true); break; case PreloadAssetTypeCode.UITexture: GameCenter.TextureManager.PreLoadTexture(AssetUtils.GetImageAssetPath(ImageTypeCode.UI, assetName), x => { OnAssetLoaded(true); }); break; case PreloadAssetTypeCode.VFXTexture: //预加载VFXTexuture的Bundle,这个Bundle在预加载之前就需要加载进来,不能等到现在再进行处理 //VFXTextureAssetsLoader.PreLoadBundle(() => { OnAssetLoaded(true); }); break; case PreloadAssetTypeCode.Font: PrefabAssetManager.SharedInstance.PreLoadPrefab(UIPoolAssetsLoader.FontPath(assetName), OnUIFontLoadFinished, true); break; case PreloadAssetTypeCode.Atlas: PrefabAssetManager.SharedInstance.PreLoadPrefab(UIPoolAssetsLoader.AtlasPath(assetName), x => { OnAssetLoaded(true); }, true); break; case PreloadAssetTypeCode.Animation: if (assetName.Contains("_")) { int index = assetName.IndexOf("_"); string occStr = assetName.Substring(0, index); string name = assetName.Substring(index + 1); int occ = -1; int.TryParse(occStr, out occ); GameCenter.AnimManager.PreLoadAnimation(ModelTypeCode.Player, occ, new string[] { name }); OnAssetLoaded(true); } else { OnAssetLoaded(false); } break; case PreloadAssetTypeCode.Form: GameCenter.PreLoadFormRoot.Add(assetName); OnAssetLoaded(true); break; case PreloadAssetTypeCode.FormAsset: PrefabAssetManager.SharedInstance.PreLoadPrefab(UIPoolAssetsLoader.FormPrefabPath(assetName, assetName), OnUIFormLoadFinished, true); break; case PreloadAssetTypeCode.UISound: GameCenter.AudioManager.PreLoadAudio(AssetUtils.GetAudioFilePath(assetName, AudioTypeCode.UI), x => { OnAssetLoaded(x != null); }); break; case PreloadAssetTypeCode.SfxSound: GameCenter.AudioManager.PreLoadAudio(AssetUtils.GetAudioFilePath(assetName, AudioTypeCode.Sfx), x => { OnAssetLoaded(x != null); }); break; case PreloadAssetTypeCode.MusicSound: GameCenter.AudioManager.PreLoadAudio(AssetUtils.GetAudioFilePath(assetName, AudioTypeCode.Music), x => { OnAssetLoaded(x != null); }); break; case PreloadAssetTypeCode.SpeechSound: GameCenter.AudioManager.PreLoadAudio(AssetUtils.GetAudioFilePath(assetName, AudioTypeCode.Speech), x => { OnAssetLoaded(x != null); }); break; case PreloadAssetTypeCode.AmbientSound: GameCenter.AudioManager.PreLoadAudio(AssetUtils.GetAudioFilePath(assetName, AudioTypeCode.Ambient), x => { OnAssetLoaded(x != null); }); break; case PreloadAssetTypeCode.VFX: case PreloadAssetTypeCode.Role: PrefabAssetManager.SharedInstance.PreLoadPrefab(assetName, x => { OnAssetLoaded(x != null); }); break; default: OnAssetLoaded(true); break; } } //加载完一个资源后 private void OnAssetLoaded(bool finish) { _loadedCount++; if (_loadedCount >= _totalCount) { if (_OnProgressHandler != null) _OnProgressHandler(1f); if (_OnFinishedHandler != null) _OnFinishedHandler(); Debug.Log("预加载完成! EndTime: " + Time.realtimeSinceStartup); } else { var pValue = (float)_loadedCount / (float)_totalCount; if (_OnProgressHandler != null) _OnProgressHandler(pValue); } } //字体单独加载完成回调 private void OnUIFontLoadFinished(PrefabAssetInfo x) { if (MemoryMonitor.Level != MemoryLevel.Low) { if (x != null && x.AssetObject != null) { var assetName = x.Name; if (!string.IsNullOrEmpty(_allChars) && assetName.Contains("UINewMainFont")) { //在读取_allChars时已经对大小进行了判断了. var font = UnityUtils.GetMonoBehaviour(x.AssetObject, "UIFont"); if (font != null) { AssemblyUtils.InvokePublicMemberMethod(font, "FillCharsInTexture", new object[] { _allChars }); } } } } OnAssetLoaded(true); } //窗体加载完成 private void OnUIFormLoadFinished(PrefabAssetInfo x) { if (x != null && x.AssetObject != null) { var assetName = x.Name; var formAsset = UnityUtils.GetMonoBehaviour(x.AssetObject, "UIFormAssetDataScript"); if (formAsset != null) { AssemblyUtils.InvokePublicMemberMethod(formAsset, "PreLoadAssets", new object[] { new Action(PreLoadAtlasOrFont) }); } } OnAssetLoaded(true); } //窗体的的字体和atlas的加载 private void PreLoadAtlasOrFont(string assetName, bool isAtlas) { if (isAtlas) { PrefabAssetManager.SharedInstance.PreLoadPrefab(UIPoolAssetsLoader.AtlasPath(assetName), null, true); } else { PrefabAssetManager.SharedInstance.PreLoadPrefab(UIPoolAssetsLoader.FontPath(assetName), null, true); } } } }