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);
}
}
}
}