8
Assets/Scripts/NBC/Runtime/Asset.meta
Normal file
8
Assets/Scripts/NBC/Runtime/Asset.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7148f149eca74238a06cee662839e8bf
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Scripts/NBC/Runtime/Asset/Editor.meta
Normal file
8
Assets/Scripts/NBC/Runtime/Asset/Editor.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 57b93d152d45c8e4db2b93e67f13f4b2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Scripts/NBC/Runtime/Asset/Runtime.meta
Normal file
8
Assets/Scripts/NBC/Runtime/Asset/Runtime.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e949dff72c03bd94a86fb9fcb59cfcff
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
3
Assets/Scripts/NBC/Runtime/Asset/Runtime/Address.meta
Normal file
3
Assets/Scripts/NBC/Runtime/Asset/Runtime/Address.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 15d567bba8474e428130cba9e1280371
|
||||
timeCreated: 1675820358
|
||||
149
Assets/Scripts/NBC/Runtime/Asset/Runtime/Address/Addressable.cs
Normal file
149
Assets/Scripts/NBC/Runtime/Asset/Runtime/Address/Addressable.cs
Normal file
@@ -0,0 +1,149 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
#if UNITY_EDITOR
|
||||
using System.Reflection;
|
||||
#endif
|
||||
|
||||
namespace NBC.Asset
|
||||
{
|
||||
public interface IAddressableImpl
|
||||
{
|
||||
public void Load();
|
||||
void UpdateBundleInfo(string bundleName);
|
||||
VersionData GetVersionData();
|
||||
PackageData GetPackageData(string packageName);
|
||||
AssetInfo GetAssetInfo(string path, Type type);
|
||||
BundleInfo GetBundleInfo(AssetInfo assetInfo);
|
||||
BundleInfo GetBundleInfo(BundleData bundleData);
|
||||
BundleInfo[] GetAllBundleInfo();
|
||||
BundleInfo[] GetAllDependBundleInfos(AssetInfo assetInfo);
|
||||
}
|
||||
|
||||
internal static class Addressable
|
||||
{
|
||||
public static Func<IAddressableImpl> CreateHandler { get; set; } = AddressableRuntimeImpl.CreateInstance;
|
||||
private static IAddressableImpl _impl;
|
||||
|
||||
public static void Load()
|
||||
{
|
||||
CreateHandlerImpl();
|
||||
_impl.Load();
|
||||
}
|
||||
|
||||
public static void UpdateBundleInfo(string bundleName)
|
||||
{
|
||||
_impl.UpdateBundleInfo(bundleName);
|
||||
}
|
||||
|
||||
#region Version
|
||||
|
||||
public static VersionData GetVersionData()
|
||||
{
|
||||
return _impl.GetVersionData();
|
||||
}
|
||||
|
||||
public static PackageData GetPackageData(string packageName)
|
||||
{
|
||||
return _impl.GetPackageData(packageName);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Asset
|
||||
|
||||
public static AssetInfo GetAssetInfo(string path, Type type)
|
||||
{
|
||||
return _impl.GetAssetInfo(path, type);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Bundle
|
||||
|
||||
public static BundleInfo GetBundleInfo(AssetInfo assetInfo)
|
||||
{
|
||||
return _impl.GetBundleInfo(assetInfo);
|
||||
}
|
||||
|
||||
public static BundleInfo GetBundleInfo(BundleData bundleData)
|
||||
{
|
||||
return _impl.GetBundleInfo(bundleData);
|
||||
}
|
||||
|
||||
public static BundleInfo[] GetAllBundleInfo()
|
||||
{
|
||||
return _impl.GetAllBundleInfo();
|
||||
}
|
||||
|
||||
public static BundleInfo[] GetAllDependBundleInfos(AssetInfo assetInfo)
|
||||
{
|
||||
return _impl.GetAllDependBundleInfos(assetInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前版本可以解压到本地缓存的bundle包
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static BundleInfo[] GetCanUnpackBundles()
|
||||
{
|
||||
var bundles = GetAllBundleInfo();
|
||||
return bundles.Where(bundle => bundle.LoadMode == BundleLoadMode.LoadFromStreaming).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前版本可以下载到本地的bundle包
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static BundleInfo[] GetCanDownloadBundles()
|
||||
{
|
||||
var bundles = GetAllBundleInfo();
|
||||
return bundles.Where(bundle => bundle.LoadMode == BundleLoadMode.LoadFromRemote).ToArray();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 内部方法
|
||||
|
||||
private static void CreateHandlerImpl()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (Const.Simulate)
|
||||
{
|
||||
_impl = GetAddressableEditImpl();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
_impl = CreateHandler();
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
/// <summary>
|
||||
/// 通过反射,实例化editor下的接口实现
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static IAddressableImpl GetAddressableEditImpl()
|
||||
{
|
||||
var ass = AppDomain.CurrentDomain.GetAssemblies()
|
||||
.First(assembly => assembly.GetName().Name == "NBC.Asset.Editor");
|
||||
var type = ass.GetType("NBC.Asset.Editor.AddressableEditImpl");
|
||||
var manifestFilePath = InvokePublicStaticMethod(type, "CreateInstance") as IAddressableImpl;
|
||||
return manifestFilePath;
|
||||
}
|
||||
|
||||
private static object InvokePublicStaticMethod(System.Type type, string method, params object[] parameters)
|
||||
{
|
||||
var methodInfo = type.GetMethod(method, BindingFlags.Public | BindingFlags.Static);
|
||||
if (methodInfo == null)
|
||||
{
|
||||
UnityEngine.Debug.LogError($"{type.FullName} not found method : {method}");
|
||||
return null;
|
||||
}
|
||||
|
||||
return methodInfo.Invoke(null, parameters);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ef00a85e62d14d759a4b4cc90d922e44
|
||||
timeCreated: 1675932162
|
||||
@@ -0,0 +1,164 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC.Asset
|
||||
{
|
||||
internal class AddressableRuntimeImpl : IAddressableImpl
|
||||
{
|
||||
public static IAddressableImpl CreateInstance()
|
||||
{
|
||||
return new AddressableRuntimeImpl();
|
||||
}
|
||||
|
||||
private VersionDataReader _versionDataReader;
|
||||
|
||||
private readonly Dictionary<string, AssetInfo> _assetInfos = new Dictionary<string, AssetInfo>();
|
||||
private readonly Dictionary<string, BundleInfo> _bundleInfos = new Dictionary<string, BundleInfo>();
|
||||
|
||||
#region Init
|
||||
|
||||
public void Load()
|
||||
{
|
||||
_versionDataReader = new VersionDataReader();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region manifest Data
|
||||
|
||||
public VersionData GetVersionData()
|
||||
{
|
||||
return _versionDataReader.VersionData;
|
||||
}
|
||||
|
||||
public PackageData GetPackageData(string packageName)
|
||||
{
|
||||
return _versionDataReader.PackageDataList.Find(p => p.Name == packageName);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Assets
|
||||
|
||||
public AssetInfo GetAssetInfo(string path, Type type)
|
||||
{
|
||||
path = _versionDataReader.GetAssetRealPath(path);
|
||||
var guid = Util.GetAssetGUID(path, type);
|
||||
if (!_assetInfos.TryGetValue(guid, out var info))
|
||||
{
|
||||
var data = _versionDataReader.GetAsset(path);
|
||||
if (data != null)
|
||||
{
|
||||
info = new AssetInfo(data, type);
|
||||
_assetInfos[info.GUID] = info;
|
||||
}
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Bundles
|
||||
|
||||
/// <summary>
|
||||
/// 刷新bundle相关信息
|
||||
/// </summary>
|
||||
public void UpdateBundleInfo(string bundleName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(bundleName))
|
||||
{
|
||||
foreach (var bundle in _bundleInfos.Values)
|
||||
{
|
||||
bundle.LoadMode = GetBundleLoadMode(bundle.Bundle);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_bundleInfos.TryGetValue(bundleName, out var bundleInfo))
|
||||
{
|
||||
bundleInfo.LoadMode = GetBundleLoadMode(bundleInfo.Bundle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public BundleInfo GetBundleInfo(AssetInfo assetInfo)
|
||||
{
|
||||
var bundleData = _versionDataReader.GetBundleByAsset(assetInfo.Path);
|
||||
return GetBundleInfo(bundleData);
|
||||
}
|
||||
|
||||
public BundleInfo GetBundleInfo(BundleData bundleData)
|
||||
{
|
||||
if (bundleData == null)
|
||||
throw new Exception("BundleData NOT NULL!");
|
||||
if (!_bundleInfos.TryGetValue(bundleData.Name, out var bundleInfo))
|
||||
{
|
||||
bundleInfo = CreateBundleInfo(bundleData);
|
||||
}
|
||||
|
||||
return bundleInfo;
|
||||
}
|
||||
|
||||
public BundleInfo[] GetAllBundleInfo()
|
||||
{
|
||||
var bundles = _versionDataReader.GetAllBundle();
|
||||
List<BundleInfo> list = new List<BundleInfo>(bundles.Count);
|
||||
foreach (var bundle in bundles)
|
||||
{
|
||||
list.Add(GetBundleInfo(bundle));
|
||||
}
|
||||
|
||||
return list.ToArray();
|
||||
}
|
||||
|
||||
public BundleInfo[] GetAllDependBundleInfos(AssetInfo assetInfo)
|
||||
{
|
||||
var arr = _versionDataReader.GetAllDependBundle(assetInfo.Path);
|
||||
if (arr != null)
|
||||
{
|
||||
List<BundleInfo> list = new List<BundleInfo>();
|
||||
foreach (var bundle in arr)
|
||||
{
|
||||
list.Add(GetBundleInfo(bundle));
|
||||
}
|
||||
|
||||
return list.ToArray();
|
||||
}
|
||||
|
||||
return Array.Empty<BundleInfo>();
|
||||
}
|
||||
|
||||
|
||||
private BundleInfo CreateBundleInfo(BundleData bundleData)
|
||||
{
|
||||
var bundleInfo = new BundleInfo(bundleData)
|
||||
{
|
||||
LoadMode = GetBundleLoadMode(bundleData)
|
||||
};
|
||||
_bundleInfos[bundleData.Name] = bundleInfo;
|
||||
return bundleInfo;
|
||||
}
|
||||
|
||||
private BundleLoadMode GetBundleLoadMode(BundleData bundleData)
|
||||
{
|
||||
if (File.Exists(bundleData.CachedDataFilePath))
|
||||
{
|
||||
return BundleLoadMode.LoadFromCache;
|
||||
}
|
||||
|
||||
|
||||
if (StreamingAssetsUtil.FileExists(bundleData.NameHash))
|
||||
{
|
||||
return BundleLoadMode.LoadFromStreaming;
|
||||
}
|
||||
|
||||
return BundleLoadMode.LoadFromRemote;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4ad9800ddd244d50b5d4c7bc18f578b9
|
||||
timeCreated: 1677723858
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 017fad8ee8a545caa126cdaad404c93d
|
||||
timeCreated: 1677636239
|
||||
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace NBC.Asset
|
||||
{
|
||||
[Serializable]
|
||||
public class AssetData
|
||||
{
|
||||
public string Name;
|
||||
public int Bundle;
|
||||
|
||||
/// <summary>
|
||||
/// 所属目录
|
||||
/// </summary>
|
||||
public int Dir;
|
||||
|
||||
// /// <summary>
|
||||
// /// 依赖的bundle
|
||||
// /// </summary>
|
||||
// public List<int> Deps = new List<int>();
|
||||
|
||||
/// <summary>
|
||||
/// 资源可寻址地址
|
||||
/// </summary>
|
||||
public string Address;
|
||||
|
||||
/// <summary>
|
||||
/// 资源真实地址
|
||||
/// </summary>
|
||||
public string Path { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 资源Bundle
|
||||
/// </summary>
|
||||
public string BundleName { get; set; }
|
||||
|
||||
|
||||
public string[] Tags { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否包含Tag
|
||||
/// </summary>
|
||||
public bool HasTag(string[] tags)
|
||||
{
|
||||
if (tags == null || tags.Length == 0)
|
||||
return false;
|
||||
if (Tags == null || Tags.Length == 0)
|
||||
return false;
|
||||
|
||||
foreach (var tag in tags)
|
||||
{
|
||||
if (Tags.Contains(tag))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 591cdedd5ee84c1c98d1d80d4c8f44fc
|
||||
timeCreated: 1677230741
|
||||
@@ -0,0 +1,114 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NBC.Asset
|
||||
{
|
||||
[Serializable]
|
||||
public class BundleData
|
||||
{
|
||||
public string Name;
|
||||
public string Hash;
|
||||
public int Size;
|
||||
|
||||
// /// <summary>
|
||||
// /// 加载方法
|
||||
// /// </summary>
|
||||
// public byte LoadMethod;
|
||||
|
||||
/// <summary>
|
||||
/// 资源包的分类标签
|
||||
/// </summary>
|
||||
public string[] Tags;
|
||||
|
||||
/// <summary>
|
||||
/// 依赖的bundleId
|
||||
/// </summary>
|
||||
public List<int> Deps = new List<int>();
|
||||
|
||||
/// <summary>
|
||||
/// 所属的包裹名称
|
||||
/// </summary>
|
||||
public string PackageName { set; get; }
|
||||
|
||||
public List<string> DependBundles { get; private set; } = new List<string>();
|
||||
|
||||
private string _nameHash = string.Empty;
|
||||
|
||||
public string NameHash
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_nameHash)) return _nameHash;
|
||||
_nameHash = Util.NameAddHash(Name, Hash);
|
||||
return _nameHash;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 内置文件路径
|
||||
/// </summary>
|
||||
private string _streamingFilePath;
|
||||
|
||||
public string StreamingFilePath
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(_streamingFilePath) == false)
|
||||
return _streamingFilePath;
|
||||
|
||||
_streamingFilePath = Const.GetStreamingPath(NameHash);
|
||||
return _streamingFilePath;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 缓存的数据文件路径
|
||||
/// </summary>
|
||||
private string _cachedDataFilePath;
|
||||
|
||||
public string CachedDataFilePath
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(_cachedDataFilePath) == false)
|
||||
return _cachedDataFilePath;
|
||||
_cachedDataFilePath = Const.GetCachePath(NameHash);
|
||||
return _cachedDataFilePath;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 远程的数据文件路径
|
||||
/// </summary>
|
||||
private string _remoteDataFilePath;
|
||||
|
||||
public string RemoteDataFilePath
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(_remoteDataFilePath) == false)
|
||||
return _remoteDataFilePath;
|
||||
_remoteDataFilePath = Const.GetRemotePath(NameHash);
|
||||
return _remoteDataFilePath;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 临时的数据文件路径
|
||||
/// </summary>
|
||||
private string _tempDataFilePath;
|
||||
|
||||
public string TempDataFilePath
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(_tempDataFilePath) == false)
|
||||
return _tempDataFilePath;
|
||||
|
||||
_tempDataFilePath = $"{CachedDataFilePath}.temp";
|
||||
return _tempDataFilePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: de6f2556c6e147afb0269b9ca02c6260
|
||||
timeCreated: 1677230723
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NBC.Asset
|
||||
{
|
||||
[Serializable]
|
||||
public class PackageData
|
||||
{
|
||||
public string Name;
|
||||
public int Def;
|
||||
public List<string> Dirs;
|
||||
public List<AssetData> Assets;
|
||||
public List<BundleData> Bundles;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 10936edd968649ecbf4b7a1bb20e84cf
|
||||
timeCreated: 1678156381
|
||||
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NBC.Asset
|
||||
{
|
||||
// [Serializable]
|
||||
// public class VersionPackagesData
|
||||
// {
|
||||
// public string Ver;
|
||||
// public string Name;
|
||||
// public string Hash;
|
||||
// public int Size;
|
||||
// public int Def;
|
||||
// public string NameHash => $"{Name}_{Hash}.json";
|
||||
// }
|
||||
//
|
||||
// [Serializable]
|
||||
// public class VersionData
|
||||
// {
|
||||
// /// <summary>
|
||||
// /// app版本号
|
||||
// /// </summary>
|
||||
// public string AppVer;
|
||||
//
|
||||
// /// <summary>
|
||||
// /// 版本包
|
||||
// /// </summary>
|
||||
// public List<VersionPackagesData> Packages = new List<VersionPackagesData>();
|
||||
//
|
||||
// /// <summary>
|
||||
// /// 导出时间
|
||||
// /// </summary>
|
||||
// public long BuildTime;
|
||||
// }
|
||||
|
||||
[Serializable]
|
||||
public class VersionPackageData
|
||||
{
|
||||
public List<PackageData> Packages = new List<PackageData>();
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class VersionData
|
||||
{
|
||||
/// <summary>
|
||||
/// app版本号
|
||||
/// </summary>
|
||||
public string AppVer;
|
||||
|
||||
/// <summary>
|
||||
/// 版本包hash
|
||||
/// </summary>
|
||||
public string Hash;
|
||||
|
||||
public long Size;
|
||||
/// <summary>
|
||||
/// 导出时间
|
||||
/// </summary>
|
||||
public long BuildTime;
|
||||
|
||||
public string NameHash => $"packages_{Hash}.json";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 671aac8f73924f1bae2ef7753fb6b239
|
||||
timeCreated: 1675820403
|
||||
@@ -0,0 +1,139 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC.Asset
|
||||
{
|
||||
internal class VersionDataReader
|
||||
{
|
||||
private readonly Dictionary<string, BundleData> _bundles = new Dictionary<string, BundleData>();
|
||||
|
||||
private readonly Dictionary<string, AssetData> _assets = new Dictionary<string, AssetData>();
|
||||
private readonly Dictionary<string, string> _addressablePath = new Dictionary<string, string>();
|
||||
public VersionData VersionData { get; private set; }
|
||||
|
||||
public List<PackageData> PackageDataList { get; private set; } = new List<PackageData>();
|
||||
|
||||
public VersionDataReader()
|
||||
{
|
||||
ReadVersionData();
|
||||
}
|
||||
|
||||
public string GetAssetRealPath(string path)
|
||||
{
|
||||
return _addressablePath.TryGetValue(path, out var realPath) ? realPath : path;
|
||||
}
|
||||
|
||||
public AssetData GetAsset(string path)
|
||||
{
|
||||
return _assets.TryGetValue(path, out var assetRef) ? assetRef : null;
|
||||
}
|
||||
|
||||
public List<BundleData> GetAllBundle()
|
||||
{
|
||||
List<BundleData> list = new List<BundleData>(_bundles.Count);
|
||||
list.AddRange(_bundles.Values);
|
||||
return list;
|
||||
}
|
||||
|
||||
public BundleData GetBundle(string name)
|
||||
{
|
||||
return _bundles.TryGetValue(name, out var bundleRef) ? bundleRef : null;
|
||||
}
|
||||
|
||||
public BundleData GetBundleByAsset(string assetPath)
|
||||
{
|
||||
var asset = GetAsset(assetPath);
|
||||
return asset == null ? null : GetBundle(asset.BundleName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取资源所需的所有bundle信息(下标0为所在包)
|
||||
/// </summary>
|
||||
/// <param name="path">资源原始地址</param>
|
||||
/// <returns></returns>
|
||||
public BundleData[] GetAllDependBundle(string path)
|
||||
{
|
||||
if (_assets.TryGetValue(path, out var assetData))
|
||||
{
|
||||
if (_bundles.TryGetValue(assetData.BundleName, out var bundleData))
|
||||
{
|
||||
var needBundle = new List<BundleData> { bundleData };
|
||||
needBundle.AddRange(bundleData.DependBundles.Select(bundle => _bundles[bundle]));
|
||||
return needBundle.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
return Array.Empty<BundleData>();
|
||||
}
|
||||
|
||||
private void ReadVersionData()
|
||||
{
|
||||
VersionData = ReadJson<VersionData>(Const.VersionFileName);
|
||||
if (VersionData != null)
|
||||
{
|
||||
var packageData =
|
||||
ReadJson<VersionPackageData>(VersionData.NameHash);
|
||||
if (packageData != null)
|
||||
{
|
||||
foreach (var package in packageData.Packages)
|
||||
{
|
||||
ReadPackage(package);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("version data is null");
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadPackage(PackageData packageData)
|
||||
{
|
||||
if (packageData != null)
|
||||
{
|
||||
foreach (var bundle in packageData.Bundles)
|
||||
{
|
||||
foreach (var dep in bundle.Deps)
|
||||
{
|
||||
var depBundle = packageData.Bundles[dep];
|
||||
if (depBundle != null)
|
||||
{
|
||||
bundle.DependBundles.Add(depBundle.Name);
|
||||
}
|
||||
}
|
||||
|
||||
bundle.PackageName = packageData.Name;
|
||||
_bundles[bundle.Name] = bundle;
|
||||
}
|
||||
|
||||
foreach (var asset in packageData.Assets)
|
||||
{
|
||||
if (asset.Dir < 0 || asset.Dir >= packageData.Dirs.Count) continue;
|
||||
if (asset.Bundle < 0 || asset.Bundle >= packageData.Bundles.Count) continue;
|
||||
var dir = packageData.Dirs[asset.Dir];
|
||||
var bundle = packageData.Bundles[asset.Bundle];
|
||||
asset.Path = $"{dir}/{asset.Name}";
|
||||
asset.BundleName = bundle.Name;
|
||||
_assets[asset.Path] = asset;
|
||||
var filePath = $"{dir}/{Path.GetFileNameWithoutExtension(asset.Name)}";
|
||||
//去除后缀后,默认加入寻址
|
||||
_addressablePath[filePath] = asset.Path;
|
||||
if (asset.Address != asset.Path)
|
||||
{
|
||||
_addressablePath[asset.Address] = asset.Path;
|
||||
}
|
||||
}
|
||||
|
||||
PackageDataList.Add(packageData);
|
||||
}
|
||||
}
|
||||
|
||||
private T ReadJson<T>(string fileName) where T : new()
|
||||
{
|
||||
return Util.ReadJson<T>(Const.GetCachePath(fileName));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: df6f17d0c94e4f9ca2145fab20c9052f
|
||||
timeCreated: 1678083955
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d09538ede05f44e185e003b29093c3c3
|
||||
timeCreated: 1677723806
|
||||
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
|
||||
namespace NBC.Asset
|
||||
{
|
||||
public class AssetInfo
|
||||
{
|
||||
private readonly AssetData _assetData;
|
||||
|
||||
// public AssetData Data => _assetData;
|
||||
|
||||
/// <summary>
|
||||
/// 资源路径
|
||||
/// </summary>
|
||||
public string Path { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 资源类型
|
||||
/// </summary>
|
||||
public Type AssetType { private set; get; }
|
||||
|
||||
|
||||
private string _providerGUID;
|
||||
|
||||
/// <summary>
|
||||
/// 唯一标识符
|
||||
/// </summary>
|
||||
public string GUID
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_providerGUID))
|
||||
return _providerGUID;
|
||||
|
||||
_providerGUID = Util.GetAssetGUID(Path, AssetType);
|
||||
return _providerGUID;
|
||||
}
|
||||
}
|
||||
|
||||
public AssetInfo(AssetData assetData, System.Type assetType)
|
||||
{
|
||||
if (assetData == null)
|
||||
throw new Exception("assetData is null!");
|
||||
|
||||
_assetData = assetData;
|
||||
AssetType = assetType;
|
||||
Path = assetData.Path;
|
||||
}
|
||||
|
||||
public AssetInfo(AssetData assetData)
|
||||
{
|
||||
if (assetData == null)
|
||||
throw new System.Exception("assetData is null!");
|
||||
|
||||
_assetData = assetData;
|
||||
AssetType = null;
|
||||
Path = assetData.Path;
|
||||
}
|
||||
|
||||
public bool HasTag(string[] tags)
|
||||
{
|
||||
return _assetData.HasTag(tags);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7edf10c26d554a3d8c03c099062093dd
|
||||
timeCreated: 1676965484
|
||||
@@ -0,0 +1,40 @@
|
||||
namespace NBC.Asset
|
||||
{
|
||||
public class BundleInfo
|
||||
{
|
||||
public readonly BundleData Bundle;
|
||||
public BundleLoadMode LoadMode;
|
||||
|
||||
|
||||
public BundleInfo(BundleData bundleData)
|
||||
{
|
||||
Bundle = bundleData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 资源地址
|
||||
/// </summary>
|
||||
public string BundlePath
|
||||
{
|
||||
get
|
||||
{
|
||||
if (LoadMode == BundleLoadMode.LoadFromStreaming)
|
||||
{
|
||||
return Bundle.StreamingFilePath;
|
||||
}
|
||||
|
||||
if (LoadMode == BundleLoadMode.LoadFromCache)
|
||||
{
|
||||
return Bundle.CachedDataFilePath;
|
||||
}
|
||||
|
||||
if (LoadMode == BundleLoadMode.LoadFromRemote)
|
||||
{
|
||||
return Bundle.RemoteDataFilePath;
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5a2f72ad8fc649bc805449e37b9540f2
|
||||
timeCreated: 1677118210
|
||||
3
Assets/Scripts/NBC/Runtime/Asset/Runtime/Asset.meta
Normal file
3
Assets/Scripts/NBC/Runtime/Asset/Runtime/Asset.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c3d07e0b392948a6952e05b39d689112
|
||||
timeCreated: 1676356201
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e23bf04f44304300ad16382736556ec2
|
||||
timeCreated: 1677058068
|
||||
@@ -0,0 +1,56 @@
|
||||
namespace NBC.Asset
|
||||
{
|
||||
internal class AssetLoadFromDatabase : IAssetLoader
|
||||
{
|
||||
public static IAssetLoader CreateInstance()
|
||||
{
|
||||
return new AssetLoadFromDatabase();
|
||||
}
|
||||
|
||||
private AssetProvider _provider;
|
||||
|
||||
public void Start(AssetProvider provider)
|
||||
{
|
||||
_provider = provider;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
var assetInfo = _provider.AssetInfo;
|
||||
var path = assetInfo.Path;
|
||||
string guid = UnityEditor.AssetDatabase.AssetPathToGUID(path);
|
||||
if (string.IsNullOrEmpty(guid))
|
||||
{
|
||||
_provider.SetStatus(NTaskStatus.Success, $"Not found asset : {path}");
|
||||
return;
|
||||
}
|
||||
|
||||
UnityEngine.Object obj;
|
||||
if (assetInfo.AssetType == null)
|
||||
obj = UnityEditor.AssetDatabase.LoadMainAssetAtPath(assetInfo.Path);
|
||||
else
|
||||
obj = UnityEditor.AssetDatabase.LoadAssetAtPath(assetInfo.Path, assetInfo.AssetType);
|
||||
|
||||
if (obj == null)
|
||||
{
|
||||
_provider.SetStatus(NTaskStatus.Fail);
|
||||
}
|
||||
else
|
||||
{
|
||||
_provider.Asset = obj;
|
||||
_provider.SetStatus(NTaskStatus.Success);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public void WaitForAsyncComplete()
|
||||
{
|
||||
Update();
|
||||
}
|
||||
|
||||
public void Destroy()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 73a25ea4518949d28d090a974722dbee
|
||||
timeCreated: 1678286041
|
||||
@@ -0,0 +1,144 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC.Asset
|
||||
{
|
||||
internal class AssetLoaderFromBundle : IAssetLoader
|
||||
{
|
||||
public static IAssetLoader CreateInstance()
|
||||
{
|
||||
return new AssetLoaderFromBundle();
|
||||
}
|
||||
|
||||
private enum Steps
|
||||
{
|
||||
LoadDependency,
|
||||
LoadAsset,
|
||||
}
|
||||
|
||||
private AssetProvider _provider;
|
||||
private AssetInfo _assetInfo;
|
||||
|
||||
private AssetBundleRequest _cacheRequest;
|
||||
private Dependency _dependency;
|
||||
private Steps _steps = Steps.LoadDependency;
|
||||
private bool _isWaitForAsyncComplete;
|
||||
|
||||
private AssetBundleRequest _assetBundleRequest;
|
||||
public AssetBundle _assetBundle;
|
||||
|
||||
public void Start(AssetProvider provider)
|
||||
{
|
||||
_provider = provider;
|
||||
_assetInfo = provider.AssetInfo;
|
||||
|
||||
_dependency = Dependency.GetAssetDependency(_assetInfo);
|
||||
_dependency.Retain();
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (_steps == Steps.LoadDependency)
|
||||
{
|
||||
if (_isWaitForAsyncComplete)
|
||||
{
|
||||
_dependency.WaitForAsyncComplete();
|
||||
}
|
||||
|
||||
if (!_dependency.IsDone) return;
|
||||
|
||||
if (!_dependency.IsSucceed)
|
||||
{
|
||||
Debug.LogError("error");
|
||||
SetStatus("dependency fail");
|
||||
}
|
||||
|
||||
var provider = _dependency.GetMainBundledProvider();
|
||||
if (provider != null && provider.AssetBundle != null)
|
||||
{
|
||||
_assetBundle = provider.AssetBundle;
|
||||
|
||||
if (_isWaitForAsyncComplete)
|
||||
{
|
||||
if (_provider.IsAll)
|
||||
{
|
||||
SetStatus(_assetBundle.LoadAssetWithSubAssets(_assetInfo.Path, _assetInfo.AssetType));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetStatus(_assetBundle.LoadAsset(_assetInfo.Path, _assetInfo.AssetType));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_assetBundleRequest = _provider.IsAll
|
||||
? _assetBundle.LoadAssetWithSubAssetsAsync(_assetInfo.Path, _assetInfo.AssetType)
|
||||
: _assetBundle.LoadAssetAsync(_assetInfo.Path, _assetInfo.AssetType);
|
||||
_steps = Steps.LoadAsset;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//失败,后续补全失败逻辑
|
||||
Debug.LogError("error1");
|
||||
SetStatus("error");
|
||||
}
|
||||
}
|
||||
else if (_steps == Steps.LoadAsset)
|
||||
{
|
||||
if (!_assetBundleRequest.isDone) return;
|
||||
if (_provider.IsAll)
|
||||
{
|
||||
SetStatus(_assetBundleRequest.allAssets);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetStatus(_assetBundleRequest.asset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void WaitForAsyncComplete()
|
||||
{
|
||||
_isWaitForAsyncComplete = true;
|
||||
|
||||
int frame = 1000;
|
||||
while (true)
|
||||
{
|
||||
frame--;
|
||||
if (frame == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Update();
|
||||
|
||||
if (_provider.IsDone)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void Destroy()
|
||||
{
|
||||
_dependency.Release();
|
||||
_assetBundleRequest = null;
|
||||
}
|
||||
|
||||
|
||||
private void SetStatus(Object asset)
|
||||
{
|
||||
_provider.Asset = asset;
|
||||
_provider.SetStatus(NTaskStatus.Success);
|
||||
}
|
||||
|
||||
private void SetStatus(Object[] allAsset)
|
||||
{
|
||||
_provider.AllAsset = allAsset;
|
||||
_provider.SetStatus(NTaskStatus.Success);
|
||||
}
|
||||
|
||||
private void SetStatus(string error)
|
||||
{
|
||||
_provider.SetStatus(NTaskStatus.Fail, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4f15a2f6e208403e8e55d45dc7e01fd1
|
||||
timeCreated: 1677551825
|
||||
@@ -0,0 +1,113 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC.Asset
|
||||
{
|
||||
internal class BundleLoaderFromDownload : IBundleLoader
|
||||
{
|
||||
private enum Steps
|
||||
{
|
||||
Download,
|
||||
Load,
|
||||
Check,
|
||||
Done,
|
||||
}
|
||||
|
||||
private BundledProvider _provider;
|
||||
private Steps _steps = Steps.Download;
|
||||
private AssetBundleCreateRequest _createRequest;
|
||||
private string _downloadPath;
|
||||
private string _loadPath;
|
||||
private bool _isWaitForAsyncComplete;
|
||||
private DownloadFileTask _downloadFileTask;
|
||||
|
||||
public AssetBundle Bundle { set; get; }
|
||||
|
||||
public void Start(BundledProvider provider)
|
||||
{
|
||||
_provider = provider;
|
||||
var bundleData = provider.BundleInfo.Bundle;
|
||||
_downloadPath = bundleData.RemoteDataFilePath;
|
||||
_loadPath = bundleData.CachedDataFilePath;
|
||||
_downloadFileTask = new DownloadFileTask(_downloadPath, bundleData.CachedDataFilePath);
|
||||
_downloadFileTask.Run();
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (_steps == Steps.Download)
|
||||
{
|
||||
if (!_downloadFileTask.IsDone) return;
|
||||
Addressable.UpdateBundleInfo(_provider.BundleInfo.Bundle.Name);
|
||||
_steps = Steps.Load;
|
||||
}
|
||||
|
||||
if (_steps == Steps.Load)
|
||||
{
|
||||
if (_isWaitForAsyncComplete)
|
||||
Bundle = AssetBundle.LoadFromFile(_loadPath);
|
||||
else
|
||||
_createRequest = AssetBundle.LoadFromFileAsync(_loadPath);
|
||||
_steps = Steps.Check;
|
||||
}
|
||||
|
||||
if (_steps == Steps.Check)
|
||||
{
|
||||
if (_createRequest != null)
|
||||
{
|
||||
if (_isWaitForAsyncComplete)
|
||||
{
|
||||
Bundle = _createRequest.assetBundle;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_createRequest.isDone)
|
||||
return;
|
||||
Bundle = _createRequest.assetBundle;
|
||||
}
|
||||
}
|
||||
|
||||
if (Bundle == null)
|
||||
{
|
||||
_steps = Steps.Done;
|
||||
_provider.SetStatus(NTaskStatus.Fail,
|
||||
$"failed load assetBundle : {_provider.BundleInfo.Bundle.Name}");
|
||||
Debug.LogError(_provider.ErrorMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
_provider.SetStatus(NTaskStatus.Success);
|
||||
_provider.AssetBundle = Bundle;
|
||||
_steps = Steps.Done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void WaitForAsyncComplete()
|
||||
{
|
||||
_isWaitForAsyncComplete = true;
|
||||
|
||||
int frame = 1000;
|
||||
while (true)
|
||||
{
|
||||
// 保险机制
|
||||
frame--;
|
||||
if (frame == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Update();
|
||||
_downloadFileTask.Process();
|
||||
|
||||
if (_provider.IsDone)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void Destroy()
|
||||
{
|
||||
_createRequest = null;
|
||||
_downloadFileTask = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b2dee1496d7247acb00dbb7af88a016c
|
||||
timeCreated: 1677558190
|
||||
@@ -0,0 +1,98 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC.Asset
|
||||
{
|
||||
internal class BundleLoaderFromLocal : IBundleLoader
|
||||
{
|
||||
private enum Steps
|
||||
{
|
||||
Load,
|
||||
Check,
|
||||
Done,
|
||||
}
|
||||
|
||||
private BundledProvider _provider;
|
||||
private Steps _steps = Steps.Load;
|
||||
private AssetBundleCreateRequest _createRequest;
|
||||
private string _loadPath;
|
||||
private bool _isWaitForAsyncComplete;
|
||||
|
||||
public AssetBundle Bundle { set; get; }
|
||||
|
||||
public void Start(BundledProvider provider)
|
||||
{
|
||||
_provider = provider;
|
||||
var info = provider.BundleInfo;
|
||||
_loadPath = info.BundlePath;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (_steps == Steps.Load)
|
||||
{
|
||||
if (_isWaitForAsyncComplete)
|
||||
Bundle = AssetBundle.LoadFromFile(_loadPath);
|
||||
else
|
||||
_createRequest = AssetBundle.LoadFromFileAsync(_loadPath);
|
||||
_steps = Steps.Check;
|
||||
}
|
||||
|
||||
if (_steps == Steps.Check)
|
||||
{
|
||||
if (_createRequest != null)
|
||||
{
|
||||
if (_isWaitForAsyncComplete)
|
||||
{
|
||||
Bundle = _createRequest.assetBundle;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_createRequest.isDone)
|
||||
return;
|
||||
Bundle = _createRequest.assetBundle;
|
||||
}
|
||||
}
|
||||
|
||||
if (Bundle == null)
|
||||
{
|
||||
_steps = Steps.Done;
|
||||
_provider.SetStatus(NTaskStatus.Fail,
|
||||
$"failed load assetBundle : {_provider.BundleInfo.Bundle.Name}");
|
||||
Debug.LogError(_provider.ErrorMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
_provider.SetStatus(NTaskStatus.Success);
|
||||
_provider.AssetBundle = Bundle;
|
||||
_steps = Steps.Done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void WaitForAsyncComplete()
|
||||
{
|
||||
_isWaitForAsyncComplete = true;
|
||||
|
||||
int frame = 1000;
|
||||
while (true)
|
||||
{
|
||||
// 保险机制
|
||||
frame--;
|
||||
if (frame == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Update();
|
||||
|
||||
if (_provider.IsDone)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void Destroy()
|
||||
{
|
||||
_createRequest = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b1157be68cf14e4ea3b8dcb2eab1f59c
|
||||
timeCreated: 1677552109
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace NBC.Asset
|
||||
{
|
||||
public interface IAssetLoader
|
||||
{
|
||||
void Start(AssetProvider provider);
|
||||
void Update();
|
||||
void WaitForAsyncComplete();
|
||||
void Destroy();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 66d37ccc10d2432497d403f43d45e6d9
|
||||
timeCreated: 1677549879
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace NBC.Asset
|
||||
{
|
||||
internal interface IBundleLoader
|
||||
{
|
||||
void Start(BundledProvider provider);
|
||||
void Update();
|
||||
void WaitForAsyncComplete();
|
||||
void Destroy();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 033c5ad1ff974e368aac38947b3702c8
|
||||
timeCreated: 1677549943
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace NBC.Asset
|
||||
{
|
||||
public interface ISceneLoader
|
||||
{
|
||||
void Start(SceneProvider provider);
|
||||
void Update();
|
||||
void WaitForAsyncComplete();
|
||||
void Destroy();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: de7de727380a4f8695304aded82565aa
|
||||
timeCreated: 1677832119
|
||||
@@ -0,0 +1,101 @@
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace NBC.Asset
|
||||
{
|
||||
internal class SceneLoadFromDatabase : ISceneLoader
|
||||
{
|
||||
public static ISceneLoader CreateInstance()
|
||||
{
|
||||
return new SceneLoadFromDatabase();
|
||||
}
|
||||
|
||||
private enum Steps
|
||||
{
|
||||
LoadDependency,
|
||||
LoadScene,
|
||||
}
|
||||
|
||||
private bool _isWaitForAsyncComplete;
|
||||
private SceneProvider _provider;
|
||||
private AssetInfo _assetInfo;
|
||||
private Steps _steps;
|
||||
private AsyncOperation _asyncOperation;
|
||||
|
||||
public void Start(SceneProvider provider)
|
||||
{
|
||||
_provider = provider;
|
||||
_assetInfo = provider.AssetInfo;
|
||||
_steps = Steps.LoadDependency;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (_steps == Steps.LoadDependency)
|
||||
{
|
||||
var scenePath = _assetInfo.Path;
|
||||
LoadSceneParameters loadSceneParameters = new LoadSceneParameters
|
||||
{
|
||||
loadSceneMode = _provider.SceneMode
|
||||
};
|
||||
if (_isWaitForAsyncComplete)
|
||||
{
|
||||
UnityEditor.SceneManagement.EditorSceneManager.LoadSceneInPlayMode(scenePath, loadSceneParameters);
|
||||
SetStatus();
|
||||
}
|
||||
else
|
||||
{
|
||||
_asyncOperation =
|
||||
UnityEditor.SceneManagement.EditorSceneManager.LoadSceneAsyncInPlayMode(scenePath,
|
||||
loadSceneParameters);
|
||||
_steps = Steps.LoadScene;
|
||||
}
|
||||
}
|
||||
else if (_steps == Steps.LoadScene)
|
||||
{
|
||||
if (!_asyncOperation.isDone) return;
|
||||
SetStatus();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public void WaitForAsyncComplete()
|
||||
{
|
||||
_isWaitForAsyncComplete = true;
|
||||
|
||||
int frame = 1000;
|
||||
while (true)
|
||||
{
|
||||
frame--;
|
||||
if (frame == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Update();
|
||||
|
||||
if (_provider.IsDone)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void Destroy()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void SetStatus()
|
||||
{
|
||||
var sceneObj = SceneManager.GetSceneAt(SceneManager.sceneCount - 1);
|
||||
_provider.SceneObject = sceneObj;
|
||||
_provider.SetStatus(NTaskStatus.Success);
|
||||
}
|
||||
|
||||
private void SetStatus(string error)
|
||||
{
|
||||
_provider.SetStatus(NTaskStatus.Fail, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 46af8c940cb3447a970be02ea0aeea4a
|
||||
timeCreated: 1677833907
|
||||
@@ -0,0 +1,144 @@
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace NBC.Asset
|
||||
{
|
||||
internal class SceneLoaderFromBundle : ISceneLoader
|
||||
{
|
||||
public static ISceneLoader CreateInstance()
|
||||
{
|
||||
return new SceneLoaderFromBundle();
|
||||
}
|
||||
|
||||
private enum Steps
|
||||
{
|
||||
LoadDependency,
|
||||
LoadScene,
|
||||
}
|
||||
|
||||
private Dependency _dependency;
|
||||
private AssetInfo _assetInfo;
|
||||
private Steps _steps = Steps.LoadDependency;
|
||||
private SceneProvider _provider;
|
||||
|
||||
private bool _isWaitForAsyncComplete;
|
||||
private AsyncOperation _asyncOperation;
|
||||
|
||||
public void Start(SceneProvider provider)
|
||||
{
|
||||
_provider = provider;
|
||||
var newAsset = true;
|
||||
if (_assetInfo == null)
|
||||
{
|
||||
_assetInfo = provider.AssetInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_assetInfo.GUID == provider.AssetInfo.GUID)
|
||||
{
|
||||
newAsset = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_assetInfo = provider.AssetInfo;
|
||||
}
|
||||
}
|
||||
|
||||
if (newAsset || _dependency == null)
|
||||
{
|
||||
_dependency = Dependency.GetAssetDependency(_assetInfo);
|
||||
_dependency.Retain();
|
||||
}
|
||||
|
||||
_steps = Steps.LoadDependency;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (_steps == Steps.LoadDependency)
|
||||
{
|
||||
if (_isWaitForAsyncComplete)
|
||||
{
|
||||
_dependency.WaitForAsyncComplete();
|
||||
}
|
||||
else if (!_dependency.IsDone) return;
|
||||
|
||||
if (!_dependency.IsSucceed)
|
||||
{
|
||||
Debug.LogError("error");
|
||||
SetStatus("dependency fail");
|
||||
}
|
||||
|
||||
var provider = _dependency.GetMainBundledProvider();
|
||||
if (provider != null && provider.AssetBundle != null)
|
||||
{
|
||||
var scenePath = Path.GetFileNameWithoutExtension(_assetInfo.Path);
|
||||
if (_isWaitForAsyncComplete)
|
||||
{
|
||||
SceneManager.LoadScene(scenePath, _provider.SceneMode);
|
||||
SetStatus();
|
||||
}
|
||||
else
|
||||
{
|
||||
_asyncOperation = SceneManager.LoadSceneAsync(scenePath, _provider.SceneMode);
|
||||
_asyncOperation.allowSceneActivation = true;
|
||||
_steps = Steps.LoadScene;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//失败,后续补全失败逻辑
|
||||
Debug.LogError("error1");
|
||||
SetStatus("error");
|
||||
}
|
||||
}
|
||||
else if (_steps == Steps.LoadScene)
|
||||
{
|
||||
if (!_asyncOperation.isDone) return;
|
||||
SetStatus();
|
||||
}
|
||||
}
|
||||
|
||||
public void WaitForAsyncComplete()
|
||||
{
|
||||
_isWaitForAsyncComplete = true;
|
||||
|
||||
int frame = 1000;
|
||||
while (true)
|
||||
{
|
||||
frame--;
|
||||
if (frame == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Update();
|
||||
|
||||
if (_provider.IsDone)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void Destroy()
|
||||
{
|
||||
_dependency.Release();
|
||||
_asyncOperation = null;
|
||||
}
|
||||
|
||||
|
||||
private void SetStatus()
|
||||
|
||||
{
|
||||
var sceneObj = SceneManager.GetSceneAt(SceneManager.sceneCount - 1);
|
||||
_provider.SceneObject = sceneObj;
|
||||
_provider.SetStatus(NTaskStatus.Success);
|
||||
}
|
||||
|
||||
|
||||
private void SetStatus(string error)
|
||||
{
|
||||
_provider.SetStatus(NTaskStatus.Fail, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: febc5527b0844fbc8d46f8315bafee24
|
||||
timeCreated: 1678027484
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 30c848f308bc4088a66095eb6f34e549
|
||||
timeCreated: 1677052587
|
||||
@@ -0,0 +1,117 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC.Asset
|
||||
{
|
||||
public class AssetProvider : ProviderBase
|
||||
{
|
||||
public static Func<IAssetLoader> CreateLoader { get; set; } = AssetLoaderFromBundle.CreateInstance;
|
||||
|
||||
private IAssetLoader _loader;
|
||||
|
||||
public AssetInfo AssetInfo { get; internal set; }
|
||||
|
||||
public bool IsAll { get; set; }
|
||||
|
||||
public UnityEngine.Object Asset { get; set; }
|
||||
|
||||
public UnityEngine.Object[] AllAsset { get; set; }
|
||||
|
||||
|
||||
protected override void OnStart()
|
||||
{
|
||||
if (_loader == null) _loader = CreateLoader();
|
||||
_loader.Start(this);
|
||||
}
|
||||
|
||||
protected override NTaskStatus OnProcess()
|
||||
{
|
||||
#if DEBUG
|
||||
DebugRecord();
|
||||
#endif
|
||||
if (IsDone) return NTaskStatus.Success;
|
||||
if (IsWaitForAsyncComplete)
|
||||
{
|
||||
_loader.WaitForAsyncComplete();
|
||||
}
|
||||
else
|
||||
{
|
||||
_loader.Update();
|
||||
}
|
||||
|
||||
return base.OnProcess();
|
||||
}
|
||||
|
||||
public override void Destroy()
|
||||
{
|
||||
Debug.Log($"卸载资源==={AssetInfo.Path}");
|
||||
base.Destroy();
|
||||
_assets.Remove(this);
|
||||
_loader.Destroy();
|
||||
_loader = null;
|
||||
}
|
||||
|
||||
#region Static
|
||||
|
||||
private static readonly List<AssetProvider> _assets = new List<AssetProvider>();
|
||||
|
||||
internal static List<AssetProvider> GetAssetProviders()
|
||||
{
|
||||
return _assets;
|
||||
}
|
||||
|
||||
internal static void ReleaseAllAssets(bool force = true)
|
||||
{
|
||||
foreach (var asset in _assets)
|
||||
{
|
||||
asset.Release(force);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void ReleaseAllAssetsByTag(string[] tags, bool force = true)
|
||||
{
|
||||
foreach (var asset in _assets)
|
||||
{
|
||||
if (asset.AssetInfo.HasTag(tags))
|
||||
{
|
||||
asset.Release(force);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static AssetProvider GetAssetProvider(AssetInfo assetInfo, bool isAll = false)
|
||||
{
|
||||
if (assetInfo == null) return null;
|
||||
AssetProvider provider = null;
|
||||
foreach (var asset in _assets)
|
||||
{
|
||||
if (asset.AssetInfo == assetInfo)
|
||||
{
|
||||
provider = asset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (provider == null)
|
||||
{
|
||||
provider = new AssetProvider
|
||||
{
|
||||
AssetInfo = assetInfo,
|
||||
IsAll = isAll
|
||||
};
|
||||
#if DEBUG
|
||||
provider.InitDebugInfo();
|
||||
#endif
|
||||
_assets.Add(provider);
|
||||
}
|
||||
|
||||
provider.Run();
|
||||
|
||||
return provider;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7e767bd7f49546e5af835e60bc4ca363
|
||||
timeCreated: 1677057856
|
||||
@@ -0,0 +1,107 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC.Asset
|
||||
{
|
||||
internal class BundledProvider : ProviderBase
|
||||
{
|
||||
public static Func<IBundleLoader> CreateLoader { get; set; } = null;
|
||||
|
||||
private IBundleLoader _loader;
|
||||
public BundleInfo BundleInfo;
|
||||
public AssetBundle AssetBundle { get; set; }
|
||||
|
||||
protected override void OnStart()
|
||||
{
|
||||
_loader.Start(this);
|
||||
}
|
||||
|
||||
protected override NTaskStatus OnProcess()
|
||||
{
|
||||
#if DEBUG
|
||||
DebugRecord();
|
||||
#endif
|
||||
if (IsDone) return NTaskStatus.Success;
|
||||
if (IsWaitForAsyncComplete)
|
||||
{
|
||||
_loader.WaitForAsyncComplete();
|
||||
}
|
||||
else
|
||||
{
|
||||
_loader.Update();
|
||||
}
|
||||
|
||||
return base.OnProcess();
|
||||
}
|
||||
|
||||
public override void Destroy()
|
||||
{
|
||||
Debug.Log($"卸载Bundle==={BundleInfo.Bundle.Name}");
|
||||
base.Destroy();
|
||||
_bundled.Remove(this);
|
||||
_loader.Destroy();
|
||||
if (AssetBundle != null)
|
||||
{
|
||||
AssetBundle.Unload(true);
|
||||
AssetBundle = null;
|
||||
}
|
||||
|
||||
_loader = null;
|
||||
}
|
||||
|
||||
#region Static
|
||||
|
||||
private static readonly List<BundledProvider> _bundled = new List<BundledProvider>();
|
||||
|
||||
internal static List<BundledProvider> GetBundleProviders()
|
||||
{
|
||||
return _bundled;
|
||||
}
|
||||
|
||||
internal static BundledProvider GetBundleProvider(BundleInfo bundleInfo)
|
||||
{
|
||||
BundledProvider provider = null;
|
||||
foreach (var bundled in _bundled)
|
||||
{
|
||||
if (bundled.BundleInfo == bundleInfo)
|
||||
{
|
||||
provider = bundled;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (provider == null)
|
||||
{
|
||||
provider = new BundledProvider
|
||||
{
|
||||
BundleInfo = bundleInfo
|
||||
};
|
||||
provider._loader = GetBundleLoader(provider);
|
||||
#if DEBUG
|
||||
provider.InitDebugInfo();
|
||||
#endif
|
||||
_bundled.Add(provider);
|
||||
}
|
||||
|
||||
provider.Run();
|
||||
|
||||
return provider;
|
||||
}
|
||||
|
||||
internal static IBundleLoader GetBundleLoader(BundledProvider provider)
|
||||
{
|
||||
var loader = CreateLoader?.Invoke();
|
||||
if (loader != null) return loader;
|
||||
var bundleInfo = provider.BundleInfo;
|
||||
if (bundleInfo.LoadMode == BundleLoadMode.LoadFromRemote)
|
||||
{
|
||||
return new BundleLoaderFromDownload();
|
||||
}
|
||||
|
||||
return new BundleLoaderFromLocal();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5796a93598ef48cfbe829a4fd48b1cc2
|
||||
timeCreated: 1677057801
|
||||
@@ -0,0 +1,99 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NBC.Asset
|
||||
{
|
||||
internal class Dependency
|
||||
{
|
||||
/// <summary>
|
||||
/// 依赖的资源包加载器列表
|
||||
/// </summary>
|
||||
internal readonly List<BundledProvider> DependBundles;
|
||||
|
||||
public Dependency(List<BundledProvider> dependBundles)
|
||||
{
|
||||
DependBundles = dependBundles;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否已经完成(无论成功或失败)
|
||||
/// </summary>
|
||||
public bool IsDone
|
||||
{
|
||||
get
|
||||
{
|
||||
foreach (var bundle in DependBundles)
|
||||
{
|
||||
if (!bundle.IsDone)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsSucceed
|
||||
{
|
||||
get
|
||||
{
|
||||
foreach (var loader in DependBundles)
|
||||
{
|
||||
if (loader.Status != NTaskStatus.Success)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public void WaitForAsyncComplete()
|
||||
{
|
||||
foreach (var bundle in DependBundles)
|
||||
{
|
||||
if (!bundle.IsDone)
|
||||
bundle.WaitForAsyncComplete();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void Retain()
|
||||
{
|
||||
foreach (var request in DependBundles)
|
||||
{
|
||||
// request.Retain();
|
||||
}
|
||||
}
|
||||
|
||||
public void Release()
|
||||
{
|
||||
foreach (var request in DependBundles)
|
||||
{
|
||||
request.Release();
|
||||
}
|
||||
}
|
||||
|
||||
public BundledProvider GetMainBundledProvider()
|
||||
{
|
||||
return DependBundles.Count > 0 ? DependBundles[0] : null;
|
||||
}
|
||||
|
||||
|
||||
#region Static
|
||||
|
||||
internal static Dependency GetAssetDependency(AssetInfo assetInfo)
|
||||
{
|
||||
var bundleInfos = Addressable.GetAllDependBundleInfos(assetInfo);
|
||||
List<BundledProvider> list = new List<BundledProvider>();
|
||||
foreach (var info in bundleInfos)
|
||||
{
|
||||
list.Add(BundledProvider.GetBundleProvider(info));
|
||||
}
|
||||
|
||||
var dep = new Dependency(list);
|
||||
return dep;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1f18e197df9a4a1dbca3cb4913cb4f4d
|
||||
timeCreated: 1677551909
|
||||
@@ -0,0 +1,110 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
|
||||
namespace NBC.Asset
|
||||
{
|
||||
public abstract class ProviderBase : NTask, IRecyclable
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否已经销毁
|
||||
/// </summary>
|
||||
public bool IsDestroyed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否可以销毁
|
||||
/// </summary>
|
||||
public bool CanDestroy => IsDone && RefCount <= 0;
|
||||
|
||||
protected bool IsWaitForAsyncComplete { private set; get; } = false;
|
||||
|
||||
public void SetStatus(NTaskStatus status, string info = "")
|
||||
{
|
||||
Status = status;
|
||||
_errorMsg = info;
|
||||
}
|
||||
|
||||
internal virtual void Run()
|
||||
{
|
||||
Retain();
|
||||
if (!IsDone && !IsRunning)
|
||||
{
|
||||
Run(TaskRunner.ProviderRunner);
|
||||
}
|
||||
}
|
||||
|
||||
#region RefCounter
|
||||
|
||||
/// <summary>
|
||||
/// 引用计数
|
||||
/// </summary>
|
||||
public int RefCount { get; private set; }
|
||||
|
||||
public void Retain()
|
||||
{
|
||||
RefCount++;
|
||||
}
|
||||
|
||||
public void Release(bool force = false)
|
||||
{
|
||||
RefCount--;
|
||||
if (force) RefCount = 0;
|
||||
if (RefCount > 0) return;
|
||||
//释放资源
|
||||
Recycler.Add(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 销毁资源对象
|
||||
/// </summary>
|
||||
public virtual void Destroy()
|
||||
{
|
||||
IsDestroyed = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 等待异步执行完毕
|
||||
/// </summary>
|
||||
public void WaitForAsyncComplete()
|
||||
{
|
||||
IsWaitForAsyncComplete = true;
|
||||
Process();
|
||||
}
|
||||
|
||||
#region Debug
|
||||
|
||||
#if DEBUG
|
||||
public string LoadScene = string.Empty;
|
||||
public string LoadTime = string.Empty;
|
||||
public long LoadTotalTime { protected set; get; }
|
||||
|
||||
// 加载耗时统计
|
||||
private bool _isRecording;
|
||||
private Stopwatch _watch;
|
||||
|
||||
internal void InitDebugInfo()
|
||||
{
|
||||
LoadScene = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name;
|
||||
LoadTime = DateTime.Now.ToString("hh:mm:ss");
|
||||
}
|
||||
|
||||
protected void DebugRecord()
|
||||
{
|
||||
if (_isRecording == false)
|
||||
{
|
||||
_isRecording = true;
|
||||
_watch = Stopwatch.StartNew();
|
||||
}
|
||||
|
||||
if (_watch == null) return;
|
||||
if (!IsDone) return;
|
||||
LoadTotalTime = _watch.ElapsedMilliseconds;
|
||||
_watch = null;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0582024b8cee499496844a7c5c204286
|
||||
timeCreated: 1677051990
|
||||
@@ -0,0 +1,122 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace NBC.Asset
|
||||
{
|
||||
public class SceneProvider : ProviderBase
|
||||
{
|
||||
public static Func<ISceneLoader> CreateLoader { get; set; } = SceneLoaderFromBundle.CreateInstance;
|
||||
private ISceneLoader _loader;
|
||||
|
||||
public AssetInfo AssetInfo { get; internal set; }
|
||||
|
||||
public UnityEngine.SceneManagement.Scene SceneObject { get; set; }
|
||||
|
||||
public LoadSceneMode SceneMode;
|
||||
private AsyncOperation _asyncOp;
|
||||
private int _priority;
|
||||
|
||||
protected override void OnStart()
|
||||
{
|
||||
_loader.Start(this);
|
||||
}
|
||||
|
||||
protected override NTaskStatus OnProcess()
|
||||
{
|
||||
#if DEBUG
|
||||
DebugRecord();
|
||||
#endif
|
||||
if (IsDone) return NTaskStatus.Success;
|
||||
if (IsWaitForAsyncComplete)
|
||||
{
|
||||
_loader.WaitForAsyncComplete();
|
||||
}
|
||||
else
|
||||
{
|
||||
_loader.Update();
|
||||
}
|
||||
|
||||
return base.OnProcess();
|
||||
}
|
||||
|
||||
public override void Destroy()
|
||||
{
|
||||
base.Destroy();
|
||||
_scenes.Remove(this);
|
||||
_loader.Destroy();
|
||||
_loader = null;
|
||||
}
|
||||
|
||||
internal override void Run()
|
||||
{
|
||||
Retain();
|
||||
if (!IsRunning)
|
||||
{
|
||||
Run(TaskRunner.ProviderRunner);
|
||||
}
|
||||
}
|
||||
|
||||
#region Static
|
||||
|
||||
private static readonly List<SceneProvider> _scenes = new List<SceneProvider>();
|
||||
|
||||
internal static List<SceneProvider> GetSceneProviders()
|
||||
{
|
||||
return _scenes;
|
||||
}
|
||||
|
||||
internal static void ReleaseAllAssets(bool force = true)
|
||||
{
|
||||
foreach (var asset in _scenes)
|
||||
{
|
||||
asset.Release(force);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void ReleaseAllAssetsByTag(string[] tags, bool force = true)
|
||||
{
|
||||
foreach (var asset in _scenes)
|
||||
{
|
||||
if (asset.AssetInfo.HasTag(tags))
|
||||
{
|
||||
asset.Release(force);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static SceneProvider GetSceneProvider(AssetInfo assetInfo, bool additive = false)
|
||||
{
|
||||
SceneProvider provider = null;
|
||||
foreach (var scene in _scenes)
|
||||
{
|
||||
if (scene.AssetInfo == assetInfo)
|
||||
{
|
||||
provider = scene;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (provider == null)
|
||||
{
|
||||
provider = new SceneProvider
|
||||
{
|
||||
AssetInfo = assetInfo,
|
||||
_loader = CreateLoader(),
|
||||
SceneMode = additive ? LoadSceneMode.Additive : LoadSceneMode.Single
|
||||
};
|
||||
#if DEBUG
|
||||
provider.InitDebugInfo();
|
||||
#endif
|
||||
_scenes.Add(provider);
|
||||
}
|
||||
|
||||
provider.Run();
|
||||
|
||||
return provider;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 64b0e1cc71b24c5c86d2229c56991e95
|
||||
timeCreated: 1677831975
|
||||
413
Assets/Scripts/NBC/Runtime/Asset/Runtime/Assets.cs
Normal file
413
Assets/Scripts/NBC/Runtime/Asset/Runtime/Assets.cs
Normal file
@@ -0,0 +1,413 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace NBC.Asset
|
||||
{
|
||||
public static class Assets
|
||||
{
|
||||
private static GameObject _monoGameObject;
|
||||
private static bool _isInitialize;
|
||||
private static NTaskStatus _initializeTaskStatus = NTaskStatus.None;
|
||||
private static string _initializeError = string.Empty;
|
||||
|
||||
|
||||
public static FTask Initialize()
|
||||
{
|
||||
if (_isInitialize)
|
||||
throw new Exception($"Repeated initialization!");
|
||||
|
||||
return InitConfirm();
|
||||
}
|
||||
|
||||
#region 资源清理
|
||||
|
||||
/// <summary>
|
||||
/// 清理所有缓存
|
||||
/// </summary>
|
||||
public static void ClearAllCache()
|
||||
{
|
||||
if (Directory.Exists(Const.SavePath))
|
||||
{
|
||||
Directory.Delete(Const.SavePath, true);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 资源加载
|
||||
|
||||
public static T Load<T>(string path) where T : Object
|
||||
{
|
||||
var assetProvider = LoadAsset(path, typeof(T));
|
||||
if (assetProvider != null)
|
||||
{
|
||||
return assetProvider.Asset as T;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static AssetProvider LoadAsset<T>(string path)
|
||||
{
|
||||
return LoadAsset(path, typeof(T));
|
||||
}
|
||||
|
||||
public static AssetProvider LoadAsset(string path, Type type)
|
||||
{
|
||||
var req = LoadAssetAsync(path, type);
|
||||
req?.WaitForAsyncComplete();
|
||||
return req;
|
||||
}
|
||||
|
||||
public static AssetProvider LoadAssetAsync<T>(string path)
|
||||
{
|
||||
return LoadAssetAsync(path, typeof(T));
|
||||
}
|
||||
|
||||
public static AssetProvider LoadAssetAsync(string path, Type type)
|
||||
{
|
||||
var assetInfo = Addressable.GetAssetInfo(path, type);
|
||||
return AssetProvider.GetAssetProvider(assetInfo);
|
||||
}
|
||||
|
||||
|
||||
public static AssetProvider LoadAssetAll<T>(string path)
|
||||
{
|
||||
return LoadAssetAll(path, typeof(T));
|
||||
}
|
||||
|
||||
public static AssetProvider LoadAssetAll(string path, Type type)
|
||||
{
|
||||
var req = LoadAssetAllAsync(path, type);
|
||||
req?.WaitForAsyncComplete();
|
||||
return req;
|
||||
}
|
||||
|
||||
public static AssetProvider LoadAssetAllAsync<T>(string path)
|
||||
{
|
||||
return LoadAssetAllAsync(path, typeof(T));
|
||||
}
|
||||
|
||||
public static AssetProvider LoadAssetAllAsync(string path, Type type)
|
||||
{
|
||||
var assetInfo = Addressable.GetAssetInfo(path, type);
|
||||
return AssetProvider.GetAssetProvider(assetInfo, true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 场景加载
|
||||
|
||||
public static SceneProvider LoadScene(string path, bool additive = false)
|
||||
{
|
||||
var assetInfo = Addressable.GetAssetInfo(path, typeof(Scene));
|
||||
if (assetInfo == null)
|
||||
{
|
||||
throw new Exception($"Scene is null,path={path}");
|
||||
}
|
||||
|
||||
return SceneProvider.GetSceneProvider(assetInfo, additive);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 资源卸载
|
||||
|
||||
/// <summary>
|
||||
/// 释放所有资源
|
||||
/// </summary>
|
||||
/// <param name="force">强制释放</param>
|
||||
public static void ReleaseAllAssets(bool force = true)
|
||||
{
|
||||
AssetProvider.ReleaseAllAssets(force);
|
||||
SceneProvider.ReleaseAllAssets(force);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据标签,释放所有资源
|
||||
/// </summary>
|
||||
/// <param name="tags">标签</param>
|
||||
/// <param name="force">强制释放</param>
|
||||
public static void ReleaseAllAssetsByTag(string[] tags, bool force = true)
|
||||
{
|
||||
AssetProvider.ReleaseAllAssetsByTag(tags, force);
|
||||
SceneProvider.ReleaseAllAssetsByTag(tags, force);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 检查解压
|
||||
|
||||
/// <summary>
|
||||
/// 可以解压的bundle包数量
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static int CanUnpackBundleCount()
|
||||
{
|
||||
var arr = Addressable.GetCanUnpackBundles();
|
||||
return arr != null ? arr.Length : 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解压资源包任务(解压本地存在的所有资源)
|
||||
/// </summary>
|
||||
/// <param name="run">自动运行</param>
|
||||
/// <returns></returns>
|
||||
public static UnpackPackagesTask CreateUnpackPackagesTask(bool run = true)
|
||||
{
|
||||
var task = new UnpackPackagesTask();
|
||||
if (run) task.Run(TaskRunner.Def);
|
||||
return task;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 检查更新
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前版本可以下载到本地的bundle包
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static List<BundleInfo> GetCanDownloadBundles()
|
||||
{
|
||||
List<BundleInfo> ret = new List<BundleInfo>();
|
||||
var bundles = Addressable.GetCanDownloadBundles();
|
||||
foreach (var bundleInfo in bundles)
|
||||
{
|
||||
var bundleData = bundleInfo.Bundle;
|
||||
//可优化。缓存所有packageName,但该逻辑理论全局只会调用一次,是否需要缓存值得考虑
|
||||
if (bundleData != null && IsNeedfulPackage(bundleData.PackageName))
|
||||
{
|
||||
ret.Add(bundleInfo);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 主动下载需要的bundles包任务
|
||||
/// </summary>
|
||||
/// <param name="downloadBundles">需要下载的bundle</param>
|
||||
/// <param name="run">自动运行</param>
|
||||
/// <returns></returns>
|
||||
public static DownloadBundlesTask CreateDownloadBundlesTask(List<BundleInfo> downloadBundles, bool run = true)
|
||||
{
|
||||
var task = new DownloadBundlesTask(downloadBundles);
|
||||
if (run) task.Run();
|
||||
return task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建检查更新任务
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static CheckUpdateTask CreateCheckUpdateTask(bool run = true)
|
||||
{
|
||||
var task = new CheckUpdateTask();
|
||||
if (run) task.Run(TaskRunner.Def);
|
||||
return task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建版本更新任务
|
||||
/// </summary>
|
||||
public static UpdateVersionTask CreateUpdateVersionTask(UpdateContext context, bool run = true)
|
||||
{
|
||||
var task = new UpdateVersionTask(context);
|
||||
if (run) task.Run();
|
||||
return task;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 默认资源包
|
||||
|
||||
private static readonly HashSet<string> _defaultPackage = new HashSet<string>();
|
||||
|
||||
/// <summary>
|
||||
/// 添加一个包进入需要列表
|
||||
/// </summary>
|
||||
/// <param name="packageName"></param>
|
||||
public static void AddNeedfulPackage(string packageName)
|
||||
{
|
||||
_defaultPackage.Add(packageName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移除一个需要的资源包
|
||||
/// </summary>
|
||||
/// <param name="packageName"></param>
|
||||
public static void RemoveNeedfulPackage(string packageName)
|
||||
{
|
||||
if (_defaultPackage.Contains(packageName)) _defaultPackage.Remove(packageName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移除全部额外需要包
|
||||
/// </summary>
|
||||
public static void RemoveAllNeedful()
|
||||
{
|
||||
_defaultPackage.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否需要这个资源包
|
||||
/// </summary>
|
||||
/// <param name="packageName"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsNeedfulPackage(string packageName)
|
||||
{
|
||||
var ret = _defaultPackage.Contains(packageName);
|
||||
if (!ret)
|
||||
{
|
||||
var package = Addressable.GetPackageData(packageName);
|
||||
if (package != null)
|
||||
{
|
||||
return package.Def == 1;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 调试
|
||||
|
||||
#if DEBUG
|
||||
private static DebugRemoteServer _debugRemoteServer;
|
||||
|
||||
|
||||
public static void StartDebugRemoteServer()
|
||||
{
|
||||
_debugRemoteServer = _monoGameObject.AddComponent<DebugRemoteServer>();
|
||||
}
|
||||
|
||||
public static void StopDebugRemoteServer()
|
||||
{
|
||||
if (_debugRemoteServer != null)
|
||||
{
|
||||
Object.DestroyImmediate(_debugRemoteServer);
|
||||
}
|
||||
}
|
||||
|
||||
public static DebugInfo GetDebugInfos()
|
||||
{
|
||||
DebugInfo info = new DebugInfo();
|
||||
info.Frame = Time.frameCount;
|
||||
var assetProviders = AssetProvider.GetAssetProviders();
|
||||
foreach (var asset in assetProviders)
|
||||
{
|
||||
var i = CreateDebugAssetInfo(asset.AssetInfo, asset.IsAll);
|
||||
SetDebugBaseInfo(asset, i);
|
||||
info.AssetInfos.Add(i);
|
||||
}
|
||||
|
||||
var sceneProviders = SceneProvider.GetSceneProviders();
|
||||
foreach (var scene in sceneProviders)
|
||||
{
|
||||
var i = CreateDebugAssetInfo(scene.AssetInfo, false);
|
||||
SetDebugBaseInfo(scene, i);
|
||||
info.AssetInfos.Add(i);
|
||||
}
|
||||
|
||||
var bundleProviders = BundledProvider.GetBundleProviders();
|
||||
foreach (var bundle in bundleProviders)
|
||||
{
|
||||
var bundleInfo = new DebugBundleInfo
|
||||
{
|
||||
BundleName = bundle.BundleInfo.Bundle.Name
|
||||
};
|
||||
SetDebugBaseInfo(bundle, bundleInfo);
|
||||
info.BundleInfos.Add(bundleInfo);
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
private static DebugAssetInfo CreateDebugAssetInfo(AssetInfo asset, bool isAll)
|
||||
{
|
||||
var assetInfo = new DebugAssetInfo
|
||||
{
|
||||
Path = asset.Path,
|
||||
Type = asset.AssetType.Name,
|
||||
IsAll = isAll,
|
||||
};
|
||||
var bundleInfos = Addressable.GetAllDependBundleInfos(asset);
|
||||
foreach (var bundle in bundleInfos)
|
||||
{
|
||||
assetInfo.Dependency.Add(bundle.Bundle.Name);
|
||||
}
|
||||
|
||||
return assetInfo;
|
||||
}
|
||||
|
||||
private static void SetDebugBaseInfo(ProviderBase provider, DebugBaseInfo info)
|
||||
{
|
||||
info.LoadScene = provider.LoadScene;
|
||||
info.Ref = provider.RefCount;
|
||||
info.Status = provider.Status.ToString();
|
||||
info.LoadTime = provider.LoadTime;
|
||||
info.LoadTotalTime = provider.LoadTotalTime;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private
|
||||
|
||||
private static void Update()
|
||||
{
|
||||
TaskRunner.Update();
|
||||
Recycler.Update();
|
||||
}
|
||||
|
||||
private static async FTask InitConfirm()
|
||||
{
|
||||
_monoGameObject = new GameObject("Assets", typeof(Mono));
|
||||
Mono.AddUpdate(Update);
|
||||
InitializationTask task;
|
||||
if (Const.Simulate)
|
||||
{
|
||||
task = new EditorInitializationTask();
|
||||
AssetProvider.CreateLoader = AssetLoadFromDatabase.CreateInstance;
|
||||
SceneProvider.CreateLoader = SceneLoadFromDatabase.CreateInstance;
|
||||
}
|
||||
else if (Const.Offline)
|
||||
{
|
||||
task = new OfflineInitializationTask();
|
||||
}
|
||||
else
|
||||
{
|
||||
task = new OnlineInitializationTask();
|
||||
}
|
||||
|
||||
if (Const.IsWebGLPlatform)
|
||||
{
|
||||
Const.RemoteUrl = $"{Application.streamingAssetsPath}/";
|
||||
}
|
||||
|
||||
task.OnCompleted(InitDone);
|
||||
task.Run(TaskRunner.Def);
|
||||
_isInitialize = true;
|
||||
await task.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化完成回调
|
||||
/// </summary>
|
||||
/// <param name="taskBase"></param>
|
||||
private static void InitDone(ITask taskBase)
|
||||
{
|
||||
Debug.Log("初始化完成===");
|
||||
_initializeTaskStatus = taskBase.Status;
|
||||
_initializeError = taskBase.ErrorMsg;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/NBC/Runtime/Asset/Runtime/Assets.cs.meta
Normal file
3
Assets/Scripts/NBC/Runtime/Asset/Runtime/Assets.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a339636ce1b94bcbb5163bf34c3e11b6
|
||||
timeCreated: 1675930154
|
||||
8
Assets/Scripts/NBC/Runtime/Asset/Runtime/Const.meta
Normal file
8
Assets/Scripts/NBC/Runtime/Asset/Runtime/Const.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: de24143fe7a345ceb02108d8cc9730e0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
51
Assets/Scripts/NBC/Runtime/Asset/Runtime/Const/Const.cs
Normal file
51
Assets/Scripts/NBC/Runtime/Asset/Runtime/Const/Const.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC.Asset
|
||||
{
|
||||
public static class Const
|
||||
{
|
||||
public const string BundleDirName = "Bundles";
|
||||
public const string VersionFileName = "version.json";
|
||||
|
||||
public static bool IsWebGLPlatform => Application.platform == RuntimePlatform.WebGLPlayer;
|
||||
|
||||
public static readonly string SavePath =
|
||||
$"{Application.persistentDataPath}{Path.DirectorySeparatorChar}{BundleDirName}{Path.DirectorySeparatorChar}";
|
||||
|
||||
public static readonly string StreamingAssetsPath =
|
||||
$"{Application.streamingAssetsPath}{Path.DirectorySeparatorChar}";
|
||||
|
||||
public static string RemoteUrl = "http://127.0.0.1:8181/";
|
||||
|
||||
public static bool Offline;
|
||||
public static bool Simulate;
|
||||
|
||||
public static int DownloadTimeOut = 10;
|
||||
|
||||
|
||||
public static string GetStreamingPath(string file)
|
||||
{
|
||||
return $"{StreamingAssetsPath}{file}";
|
||||
}
|
||||
|
||||
public static string GetCachePath(string file)
|
||||
{
|
||||
return $"{SavePath}{file}";
|
||||
}
|
||||
|
||||
public static string GetCacheTempPath(string file)
|
||||
{
|
||||
return $"{SavePath}{file}.temp";
|
||||
}
|
||||
|
||||
public static string GetRemotePath(string file)
|
||||
{
|
||||
if (!Application.isEditor && IsWebGLPlatform)
|
||||
{
|
||||
return $"{RemoteUrl}/{file}";
|
||||
}
|
||||
return $"{RemoteUrl}{BundleDirName}/{file}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: de19e53b3f774094918543bbbc7318a0
|
||||
timeCreated: 1624159347
|
||||
3
Assets/Scripts/NBC/Runtime/Asset/Runtime/Enums.meta
Normal file
3
Assets/Scripts/NBC/Runtime/Asset/Runtime/Enums.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7239be5c8a2a45ff91ff7118816b9c9b
|
||||
timeCreated: 1677663981
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace NBC.Asset
|
||||
{
|
||||
public enum BundleLoadMode
|
||||
{
|
||||
None,
|
||||
LoadFromStreaming,
|
||||
LoadFromCache,
|
||||
LoadFromRemote
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 43bdba8ab37f4164913472c931edd6e4
|
||||
timeCreated: 1677663989
|
||||
3
Assets/Scripts/NBC/Runtime/Asset/Runtime/Services.meta
Normal file
3
Assets/Scripts/NBC/Runtime/Asset/Runtime/Services.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dff0030f0ed04cc6a834c994e98f2300
|
||||
timeCreated: 1677125510
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 31105beb84d840a3a8aa41ec7fecf129
|
||||
timeCreated: 1679673084
|
||||
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NBC.Asset
|
||||
{
|
||||
#if DEBUG
|
||||
[Serializable]
|
||||
public class DebugBaseInfo
|
||||
{
|
||||
public int Ref;
|
||||
public string LoadScene;
|
||||
public string LoadTime;
|
||||
public long LoadTotalTime;
|
||||
public string Status;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class DebugAssetInfo : DebugBaseInfo
|
||||
{
|
||||
public string Path;
|
||||
public string Type;
|
||||
public bool IsAll;
|
||||
public List<string> Dependency = new List<string>();
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class DebugBundleInfo : DebugBaseInfo
|
||||
{
|
||||
public string BundleName;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class DebugInfo
|
||||
{
|
||||
public int Frame;
|
||||
public List<DebugAssetInfo> AssetInfos = new List<DebugAssetInfo>();
|
||||
public List<DebugBundleInfo> BundleInfos = new List<DebugBundleInfo>();
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2db971d4daa94c33bf490be190061969
|
||||
timeCreated: 1679673090
|
||||
@@ -0,0 +1,117 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC.Asset
|
||||
{
|
||||
#if DEBUG
|
||||
|
||||
public class DebugRemoteServer : MonoBehaviour
|
||||
{
|
||||
static HttpListener _httpListener;
|
||||
|
||||
private readonly Queue<HttpListenerContext> _contexts = new Queue<HttpListenerContext>();
|
||||
|
||||
void Start()
|
||||
{
|
||||
_httpListener = new HttpListener();
|
||||
//定义url及端口号,通常设置为配置文件
|
||||
_httpListener.Prefixes.Add("http://+:8080/");
|
||||
//启动监听器
|
||||
_httpListener.Start();
|
||||
_httpListener.BeginGetContext(Result, null);
|
||||
var ip = GetIP();
|
||||
Debug.Log($"调试服务端初始化完毕ip={ip},正在等待调试客户端请求,时间:{DateTime.Now}");
|
||||
}
|
||||
|
||||
private void Result(IAsyncResult ar)
|
||||
{
|
||||
//继续异步监听
|
||||
_httpListener.BeginGetContext(Result, null);
|
||||
var guid = Guid.NewGuid().ToString();
|
||||
Debug.Log($"接到新的请求:{guid},时间:{DateTime.Now}");
|
||||
//获得context对象
|
||||
var context = _httpListener.EndGetContext(ar);
|
||||
_contexts.Enqueue(context);
|
||||
}
|
||||
|
||||
|
||||
private string HandleRequest(HttpListenerRequest request, HttpListenerResponse response)
|
||||
{
|
||||
response.StatusDescription = "200";
|
||||
response.StatusCode = 200;
|
||||
try
|
||||
{
|
||||
var info = Assets.GetDebugInfos();
|
||||
var json = JsonUtility.ToJson(info, true);
|
||||
return json;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
response.StatusDescription = "404";
|
||||
response.StatusCode = 404;
|
||||
return e.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
HandleContext();
|
||||
}
|
||||
|
||||
private void HandleContext()
|
||||
{
|
||||
if (_contexts.Count < 1) return;
|
||||
var context = _contexts.Dequeue();
|
||||
var request = context.Request;
|
||||
var response = context.Response;
|
||||
// 如果是js的ajax请求,还可以设置跨域的ip地址与参数
|
||||
context.Response.AppendHeader("Access-Control-Allow-Origin", "*");
|
||||
context.Response.ContentType = "text/plain;charset=UTF-8";
|
||||
context.Response.AddHeader("Content-type", "text/json"); //添加响应头信息
|
||||
context.Response.ContentEncoding = Encoding.UTF8;
|
||||
|
||||
string returnObj = HandleRequest(request, response); //定义返回客户端的信息
|
||||
|
||||
Debug.Log("返回内容=" + returnObj);
|
||||
var returnByteArr = Encoding.UTF8.GetBytes(returnObj); //设置客户端返回信息的编码
|
||||
try
|
||||
{
|
||||
using (var stream = response.OutputStream)
|
||||
{
|
||||
//把处理信息返回到客户端
|
||||
stream.Write(returnByteArr, 0, returnByteArr.Length);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogError($"远程调试异常:{ex}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取本机IP
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private string GetIP()
|
||||
{
|
||||
try
|
||||
{
|
||||
var ips = Dns.GetHostAddresses(Dns.GetHostName());
|
||||
var localIp = ips.First(ip => ip.AddressFamily == AddressFamily.InterNetwork);
|
||||
return localIp.ToString();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError(e);
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 32cd4999e50b4e2980d22792f53a5f40
|
||||
timeCreated: 1679831911
|
||||
@@ -0,0 +1,41 @@
|
||||
namespace NBC.Asset
|
||||
{
|
||||
public struct DecryptFileInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 资源包名称
|
||||
/// </summary>
|
||||
public string BundleName;
|
||||
|
||||
/// <summary>
|
||||
/// 文件路径
|
||||
/// </summary>
|
||||
public string FilePath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解密类服务接口
|
||||
/// </summary>
|
||||
public interface IDecryptionServices
|
||||
{
|
||||
/// <summary>
|
||||
/// 文件偏移解密方法
|
||||
/// </summary>
|
||||
ulong LoadFromFileOffset(DecryptFileInfo fileInfo);
|
||||
|
||||
/// <summary>
|
||||
/// 文件内存解密方法
|
||||
/// </summary>
|
||||
byte[] LoadFromMemory(DecryptFileInfo fileInfo);
|
||||
|
||||
/// <summary>
|
||||
/// 文件流解密方法
|
||||
/// </summary>
|
||||
System.IO.FileStream LoadFromStream(DecryptFileInfo fileInfo);
|
||||
|
||||
/// <summary>
|
||||
/// 文件流解密的托管缓存大小
|
||||
/// </summary>
|
||||
uint GetManagedReadBufferSize();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 93a19c9344864bcaaa364b72644b8df1
|
||||
timeCreated: 1677125520
|
||||
@@ -0,0 +1,65 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NBC.Asset
|
||||
{
|
||||
public interface IRecyclable
|
||||
{
|
||||
bool IsDestroyed { get; }
|
||||
bool CanDestroy { get; }
|
||||
void Destroy();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 资源回收器
|
||||
/// </summary>
|
||||
public static class Recycler
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前运行的回收任务
|
||||
/// </summary>
|
||||
static readonly List<IRecyclable> Coroutines = new List<IRecyclable>();
|
||||
|
||||
/// <summary>
|
||||
/// 准备要运行的回收任务
|
||||
/// </summary>
|
||||
static readonly List<IRecyclable> ReadyTask = new List<IRecyclable>();
|
||||
|
||||
|
||||
public static void Add(IRecyclable recyclable)
|
||||
{
|
||||
ReadyTask.Add(recyclable);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 取消回收
|
||||
/// </summary>
|
||||
/// <param name="recyclable"></param>
|
||||
public static void Cancel(IRecyclable recyclable)
|
||||
{
|
||||
ReadyTask.Remove(recyclable);
|
||||
}
|
||||
|
||||
public static void Update()
|
||||
{
|
||||
//正在加载时,不卸载资源
|
||||
if (TaskRunner.ProviderRunner.RunningTaskNum > 0) return;
|
||||
for (var i = 0; i < ReadyTask.Count; i++)
|
||||
{
|
||||
var task = ReadyTask[i];
|
||||
if (!task.CanDestroy) continue;
|
||||
ReadyTask.RemoveAt(i);
|
||||
Coroutines.Add(task);
|
||||
i--;
|
||||
}
|
||||
|
||||
for (var i = 0; i < Coroutines.Count; i++)
|
||||
{
|
||||
var task = Coroutines[i];
|
||||
Coroutines.RemoveAt(i);
|
||||
i--;
|
||||
if (task.IsDestroyed) continue;
|
||||
if (task.CanDestroy) task.Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0a68b7437aa942838124a1717199c5cb
|
||||
timeCreated: 1679229337
|
||||
3
Assets/Scripts/NBC/Runtime/Asset/Runtime/Tasks.meta
Normal file
3
Assets/Scripts/NBC/Runtime/Asset/Runtime/Tasks.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ad5d171e13704e538c9ea9f8ab3a2725
|
||||
timeCreated: 1678173529
|
||||
@@ -0,0 +1,16 @@
|
||||
namespace NBC.Asset
|
||||
{
|
||||
// public class AssetTaskBase : Task
|
||||
// {
|
||||
// public override void Run(IRunner runner = null)
|
||||
// {
|
||||
// Reset();
|
||||
// if (runner == null)
|
||||
// {
|
||||
// runner = TaskRunner.DefRunner;
|
||||
// }
|
||||
//
|
||||
// runner.Run(this);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a230a7ede67349d0ac9560cbfc937cbf
|
||||
timeCreated: 1678766484
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 26f8ef4bac2749ff9c5eba207ffc611f
|
||||
timeCreated: 1678178605
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NBC.Asset
|
||||
{
|
||||
/// <summary>
|
||||
/// 下载当前版本资源包任务
|
||||
/// </summary>
|
||||
public class DownloadBundlesTask : DownloadTaskBase
|
||||
{
|
||||
private readonly SequenceTaskCollection _taskList = new SequenceTaskCollection();
|
||||
private readonly List<BundleInfo> _downloadBundles;
|
||||
|
||||
public DownloadBundlesTask(List<BundleInfo> downloadBundles)
|
||||
{
|
||||
_downloadBundles = downloadBundles;
|
||||
}
|
||||
|
||||
protected override void OnStart()
|
||||
{
|
||||
foreach (var bundle in _downloadBundles)
|
||||
{
|
||||
if (bundle.LoadMode != BundleLoadMode.LoadFromRemote) continue;
|
||||
var bundleData = bundle.Bundle;
|
||||
_taskList.AddTask(new DownloadFileTask(bundleData.RemoteDataFilePath, bundleData.CachedDataFilePath,
|
||||
bundleData.Hash));
|
||||
}
|
||||
|
||||
_taskList.Run(TaskRunner.DownloadRunner);
|
||||
}
|
||||
|
||||
protected override NTaskStatus OnProcess()
|
||||
{
|
||||
return _taskList.IsDone ? NTaskStatus.Success : NTaskStatus.Running;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dbe7d222c526467784688d950118b1b4
|
||||
timeCreated: 1678689987
|
||||
@@ -0,0 +1,12 @@
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace NBC.Asset
|
||||
{
|
||||
public class DownloadCertificateHandler : CertificateHandler
|
||||
{
|
||||
protected override bool ValidateCertificate(byte[] certificateData)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2f6add9368cc45bcb0720de176a19000
|
||||
timeCreated: 1679280715
|
||||
@@ -0,0 +1,300 @@
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace NBC.Asset
|
||||
{
|
||||
/// <summary>
|
||||
/// 下载文件
|
||||
/// </summary>
|
||||
public class DownloadFileTask : DownloadTaskBase
|
||||
{
|
||||
private const string DownloadHeaderKey = "Content-Length";
|
||||
private const int RetryDownloadCount = 3;
|
||||
|
||||
public readonly string DownloadPath;
|
||||
|
||||
public readonly string SavePath;
|
||||
public readonly string FileHash;
|
||||
|
||||
/// <summary>
|
||||
/// 开启断点续传
|
||||
/// </summary>
|
||||
public bool ReDownload = true;
|
||||
|
||||
public DownloadFileTask(string path, string savePath, string hash = "")
|
||||
{
|
||||
DownloadPath = path;
|
||||
SavePath = savePath;
|
||||
FileHash = hash;
|
||||
}
|
||||
|
||||
public enum DownLoadStatus
|
||||
{
|
||||
None,
|
||||
GetHeader,
|
||||
PrepareDownload,
|
||||
Download,
|
||||
VerifyingFile,
|
||||
Success,
|
||||
Failed,
|
||||
}
|
||||
|
||||
private ulong _downloadTotalSize = 1;
|
||||
private UnityWebRequest _content;
|
||||
private UnityWebRequest _header;
|
||||
private bool _isAbort;
|
||||
private ulong _latestDownloadBytes;
|
||||
private float _latestDownloadRealtime;
|
||||
private ulong _fileOriginLength;
|
||||
private int RetryCount;
|
||||
|
||||
private long ResponseCode = 0;
|
||||
|
||||
public DownLoadStatus DownloadStatus { get; protected internal set; } = DownLoadStatus.None;
|
||||
public override float Progress => DownloadedBytes * 1f / DownloadTotalSize;
|
||||
|
||||
public ulong DownloadedBytes { get; protected set; }
|
||||
|
||||
public ulong DownloadTotalSize
|
||||
{
|
||||
get => _downloadTotalSize;
|
||||
set
|
||||
{
|
||||
_downloadTotalSize = value;
|
||||
if (_downloadTotalSize < 1) _downloadTotalSize = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void Abort()
|
||||
{
|
||||
Fail("abort");
|
||||
Dispose();
|
||||
}
|
||||
|
||||
protected override void OnStart()
|
||||
{
|
||||
DownloadStatus = DownLoadStatus.GetHeader;
|
||||
}
|
||||
|
||||
protected override NTaskStatus OnProcess()
|
||||
{
|
||||
if (DownloadStatus == DownLoadStatus.GetHeader)
|
||||
{
|
||||
_header = UnityWebRequest.Head(DownloadPath);
|
||||
_header.SendWebRequest();
|
||||
DownloadStatus = DownLoadStatus.PrepareDownload;
|
||||
}
|
||||
|
||||
if (DownloadStatus == DownLoadStatus.PrepareDownload)
|
||||
{
|
||||
if (_header == null)
|
||||
{
|
||||
Fail($"get header info error");
|
||||
Debug.LogError("get header info error");
|
||||
return NTaskStatus.Fail;
|
||||
}
|
||||
|
||||
if (!_header.isDone) return NTaskStatus.Running;
|
||||
|
||||
Reset();
|
||||
//远程文件信息
|
||||
var value = _header.GetResponseHeader(DownloadHeaderKey);
|
||||
if (ulong.TryParse(value, out var totalSize))
|
||||
{
|
||||
DownloadTotalSize = totalSize;
|
||||
}
|
||||
|
||||
if (ReDownload)
|
||||
{
|
||||
//读取未下载完成的文件信息
|
||||
var tempInfo = new FileInfo(SavePath);
|
||||
if (tempInfo.Exists)
|
||||
{
|
||||
_fileOriginLength = (ulong)tempInfo.Length;
|
||||
if (_fileOriginLength == DownloadTotalSize)
|
||||
{
|
||||
DownloadedBytes = _fileOriginLength;
|
||||
DownloadStatus = DownLoadStatus.VerifyingFile;
|
||||
return NTaskStatus.Running;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_fileOriginLength = 0;
|
||||
}
|
||||
|
||||
_content = UnityWebRequest.Get(DownloadPath);
|
||||
if (_fileOriginLength > 0)
|
||||
{
|
||||
Debug.Log($"断点续传===={_fileOriginLength} path={DownloadPath}");
|
||||
#if UNITY_2019_1_OR_NEWER
|
||||
_content.SetRequestHeader("Range", $"bytes={_fileOriginLength}-");
|
||||
_content.downloadHandler = new DownloadHandlerFile(SavePath, true);
|
||||
#else
|
||||
_request.DownloadedBytes = 0;
|
||||
_content.downloadHandler = new DownloadHandlerFile(TempPath);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
_content.downloadHandler = new DownloadHandlerFile(SavePath);
|
||||
}
|
||||
|
||||
_content.certificateHandler = new DownloadCertificateHandler();
|
||||
_content.disposeDownloadHandlerOnDispose = true;
|
||||
_content.disposeCertificateHandlerOnDispose = true;
|
||||
_content.disposeUploadHandlerOnDispose = true;
|
||||
_content.SendWebRequest();
|
||||
DownloadStatus = DownLoadStatus.Download;
|
||||
}
|
||||
|
||||
if (DownloadStatus == DownLoadStatus.Download)
|
||||
{
|
||||
DownloadedBytes = _fileOriginLength + _content.downloadedBytes;
|
||||
if (!_content.isDone)
|
||||
{
|
||||
CheckTimeout();
|
||||
return NTaskStatus.Running;
|
||||
}
|
||||
|
||||
bool hasError = false;
|
||||
// 检查网络错误
|
||||
#if UNITY_2020_3_OR_NEWER
|
||||
if (_content.result != UnityWebRequest.Result.Success)
|
||||
{
|
||||
hasError = true;
|
||||
_errorMsg = _content.error;
|
||||
ResponseCode = _content.responseCode;
|
||||
}
|
||||
#else
|
||||
if (_content.isNetworkError || _content.isHttpError)
|
||||
{
|
||||
hasError = true;
|
||||
_errorMsg = _content.error;
|
||||
ResponseCode = _content.responseCode;
|
||||
}
|
||||
#endif
|
||||
// 如果网络异常
|
||||
if (hasError)
|
||||
{
|
||||
RetryCount++;
|
||||
if (RetryCount <= RetryDownloadCount)
|
||||
{
|
||||
Debug.Log($"网络异常 重新开始下载={DownloadPath} code={ResponseCode} msg={_content.error}");
|
||||
//重新开始下载
|
||||
DownloadStatus = DownLoadStatus.PrepareDownload;
|
||||
}
|
||||
else
|
||||
{
|
||||
//重试后还是网络错误,直接失败
|
||||
Debug.Log("重试后还是网络错误,直接失败");
|
||||
DownloadStatus = DownLoadStatus.Failed;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DownloadStatus = DownLoadStatus.VerifyingFile;
|
||||
}
|
||||
}
|
||||
|
||||
if (DownloadStatus == DownLoadStatus.VerifyingFile)
|
||||
{
|
||||
Dispose();
|
||||
var tryPass = false;
|
||||
var tempInfo = new FileInfo(SavePath);
|
||||
|
||||
if (tempInfo.Exists)
|
||||
{
|
||||
if (tempInfo.Length == (long)DownloadTotalSize)
|
||||
{
|
||||
tryPass = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorMsg = "file size error";
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(FileHash))
|
||||
{
|
||||
var hash = Util.ComputeHash(SavePath);
|
||||
if (FileHash.Equals(hash))
|
||||
{
|
||||
tryPass = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorMsg = "file hash error";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorMsg = "file not exists";
|
||||
}
|
||||
|
||||
if (!tryPass)
|
||||
{
|
||||
// 验证失败后删除文件
|
||||
if (File.Exists(SavePath))
|
||||
File.Delete(SavePath);
|
||||
Debug.Log("验证失败后删除文件,尝试重新下载");
|
||||
//重新下载
|
||||
DownloadStatus = DownLoadStatus.PrepareDownload;
|
||||
}
|
||||
else
|
||||
{
|
||||
DownloadStatus = DownLoadStatus.Success;
|
||||
}
|
||||
}
|
||||
|
||||
if (DownloadStatus == DownLoadStatus.Success)
|
||||
{
|
||||
return NTaskStatus.Success;
|
||||
}
|
||||
|
||||
if (DownloadStatus == DownLoadStatus.Failed)
|
||||
{
|
||||
return NTaskStatus.Fail;
|
||||
}
|
||||
|
||||
return NTaskStatus.Running;
|
||||
}
|
||||
|
||||
|
||||
private void CheckTimeout()
|
||||
{
|
||||
if (_isAbort) return;
|
||||
|
||||
if (_latestDownloadBytes != DownloadedBytes)
|
||||
{
|
||||
_latestDownloadBytes = DownloadedBytes;
|
||||
_latestDownloadRealtime = Time.realtimeSinceStartup;
|
||||
}
|
||||
|
||||
float offset = Time.realtimeSinceStartup - _latestDownloadRealtime;
|
||||
if (_latestDownloadRealtime > 0 && offset > Const.DownloadTimeOut)
|
||||
{
|
||||
_content.Abort();
|
||||
_isAbort = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void Dispose()
|
||||
{
|
||||
if (_header != null)
|
||||
{
|
||||
_header.Dispose();
|
||||
_header = null;
|
||||
}
|
||||
|
||||
if (_content != null)
|
||||
{
|
||||
_content.Dispose();
|
||||
_content = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fc534770270e47bd9b36acb09ba8bad9
|
||||
timeCreated: 1678176990
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace NBC.Asset
|
||||
{
|
||||
public class DownloadRunner: Runner
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b4f1c82b77b844fca292c3226b3a1620
|
||||
timeCreated: 1678761539
|
||||
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
|
||||
namespace NBC.Asset
|
||||
{
|
||||
public class DownloadTaskBase : NTask
|
||||
{
|
||||
public virtual void Run()
|
||||
{
|
||||
Run(TaskRunner.DownloadRunner);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 321c6ff70e3b45138a9af2585706447f
|
||||
timeCreated: 1678762460
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 986e39ec068243938bc33d4beb6931f7
|
||||
timeCreated: 1678178617
|
||||
@@ -0,0 +1,22 @@
|
||||
namespace NBC.Asset
|
||||
{
|
||||
/// <summary>
|
||||
/// 编辑器初始化任务
|
||||
/// </summary>
|
||||
internal sealed class EditorInitializationTask : InitializationTask
|
||||
{
|
||||
public override float Progress => _taskList.Progress;
|
||||
private readonly SequenceTaskCollection _taskList = new SequenceTaskCollection();
|
||||
|
||||
protected override void OnStart()
|
||||
{
|
||||
_taskList.AddTask(new RunFunctionTask(Addressable.Load));
|
||||
_taskList.Run(TaskRunner.Def);
|
||||
}
|
||||
|
||||
protected override NTaskStatus OnProcess()
|
||||
{
|
||||
return _taskList.IsDone ? NTaskStatus.Success : NTaskStatus.Running;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a024ad33e47f472bac1560a1445a86e0
|
||||
timeCreated: 1678289705
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace NBC.Asset
|
||||
{
|
||||
public abstract class InitializationTask : NTask
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0ddf142fca6745ffab9246551b920fb5
|
||||
timeCreated: 1678178623
|
||||
@@ -0,0 +1,25 @@
|
||||
namespace NBC.Asset
|
||||
{
|
||||
/// <summary>
|
||||
/// 离线模式初始化任务
|
||||
/// </summary>
|
||||
internal sealed class OfflineInitializationTask : InitializationTask
|
||||
{
|
||||
public override float Progress => _taskList.Progress;
|
||||
private readonly SequenceTaskCollection _taskList = new SequenceTaskCollection();
|
||||
|
||||
protected override void OnStart()
|
||||
{
|
||||
_taskList.AddTask(new CheckCoverInstallTask());
|
||||
_taskList.AddTask(new UnpackVersionTask());
|
||||
_taskList.AddTask(new CheckUnpackPackageTask());
|
||||
_taskList.AddTask(new RunFunctionTask(Addressable.Load));
|
||||
_taskList.Run(TaskRunner.Def);
|
||||
}
|
||||
|
||||
protected override NTaskStatus OnProcess()
|
||||
{
|
||||
return _taskList.IsDone ? _taskList.Status : NTaskStatus.Running;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ae221ab297cd4bad9ee57abccd8bf15a
|
||||
timeCreated: 1678289694
|
||||
@@ -0,0 +1,26 @@
|
||||
namespace NBC.Asset
|
||||
{
|
||||
/// <summary>
|
||||
/// 线上模式初始化任务
|
||||
/// 优先从persistentData读取,如果没有,则从StreamingAssets拷贝清单文件到解压目录
|
||||
/// </summary>
|
||||
internal sealed class OnlineInitializationTask : InitializationTask
|
||||
{
|
||||
public override float Progress => _taskList.Progress;
|
||||
private readonly SequenceTaskCollection _taskList = new SequenceTaskCollection();
|
||||
|
||||
protected override void OnStart()
|
||||
{
|
||||
_taskList.AddTask(new CheckCoverInstallTask());
|
||||
_taskList.AddTask(new UnpackVersionTask(true));
|
||||
_taskList.AddTask(new CheckUnpackPackageTask(true));
|
||||
_taskList.AddTask(new RunFunctionTask(Addressable.Load));
|
||||
_taskList.Run(TaskRunner.Def);
|
||||
}
|
||||
|
||||
protected override NTaskStatus OnProcess()
|
||||
{
|
||||
return _taskList.IsDone ? _taskList.Status : NTaskStatus.Running;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f61ebb0aa33b4ad29959494481b9f791
|
||||
timeCreated: 1678289682
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4eb2452a725944268e0beb871bbd6a22
|
||||
timeCreated: 1678290546
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace NBC.Asset
|
||||
{
|
||||
/// <summary>
|
||||
/// 检查是否覆盖安装相关操作
|
||||
/// </summary>
|
||||
public class CheckCoverInstallTask : NTask
|
||||
{
|
||||
protected override NTaskStatus OnProcess()
|
||||
{
|
||||
return NTaskStatus.Success;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5320f83282e844c398ba79be297eabca
|
||||
timeCreated: 1678291123
|
||||
@@ -0,0 +1,38 @@
|
||||
using System.IO;
|
||||
|
||||
namespace NBC.Asset
|
||||
{
|
||||
/// <summary>
|
||||
/// 检查是否需要解压package清单文件
|
||||
/// </summary>
|
||||
public class CheckUnpackPackageTask : NTask
|
||||
{
|
||||
private readonly ParallelTaskCollection _taskList = new ParallelTaskCollection();
|
||||
private readonly bool _download;
|
||||
|
||||
public CheckUnpackPackageTask(bool download = false)
|
||||
{
|
||||
_download = download;
|
||||
}
|
||||
|
||||
protected override void OnStart()
|
||||
{
|
||||
var versionData = Util.ReadJson<VersionData>(Const.GetCachePath(Const.VersionFileName));
|
||||
if (versionData != null)
|
||||
{
|
||||
var cachePath = Const.GetCachePath(versionData.NameHash);
|
||||
if (!File.Exists(cachePath))
|
||||
{
|
||||
_taskList.AddTask(new UnpackFileTask(versionData.NameHash, _download));
|
||||
}
|
||||
}
|
||||
|
||||
_taskList.Run(TaskRunner.Def);
|
||||
}
|
||||
|
||||
protected override NTaskStatus OnProcess()
|
||||
{
|
||||
return _taskList.IsDone ? _taskList.Status : NTaskStatus.Running;
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user