111
This commit is contained in:
@@ -6,6 +6,8 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEditor.Build.Pipeline;
|
using UnityEditor.Build.Pipeline;
|
||||||
|
|
||||||
|
namespace Tuan.GameFramework
|
||||||
|
{
|
||||||
public class BuildTool
|
public class BuildTool
|
||||||
{
|
{
|
||||||
[MenuItem("Tools/打包Preload")]
|
[MenuItem("Tools/打包Preload")]
|
||||||
@@ -84,5 +86,4 @@ public class BuildTool
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -2,7 +2,8 @@ using UnityEditor;
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
|
namespace Tuan.GameFramework
|
||||||
|
{
|
||||||
public class CopyHotDll
|
public class CopyHotDll
|
||||||
{
|
{
|
||||||
[MenuItem("Tools/更新生成PreloadDll")]
|
[MenuItem("Tools/更新生成PreloadDll")]
|
||||||
@@ -57,3 +58,4 @@ public class CopyHotDll
|
|||||||
Debug.Log("copy over");
|
Debug.Log("copy over");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
15
Assets/GameFramework/Runtime/Asset.cs
Normal file
15
Assets/GameFramework/Runtime/Asset.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
using Cysharp.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
using YooAsset;
|
||||||
|
|
||||||
|
namespace Tuan.GameFramework
|
||||||
|
{
|
||||||
|
public class Asset : MonoBehaviour
|
||||||
|
{
|
||||||
|
async UniTask LoadAsync(string name)
|
||||||
|
{
|
||||||
|
AssetHandle handle = YooAssets.LoadAssetAsync(name);
|
||||||
|
await handle.ToUniTask();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
2
Assets/GameFramework/Runtime/Asset.cs.meta
Normal file
2
Assets/GameFramework/Runtime/Asset.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d9170e9f660395d47b0f02466e5fd091
|
||||||
@@ -2,6 +2,8 @@ using Cysharp.Threading.Tasks;
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using YooAsset;
|
using YooAsset;
|
||||||
|
|
||||||
|
namespace Tuan.GameFramework
|
||||||
|
{
|
||||||
public class Boot : MonoBehaviour
|
public class Boot : MonoBehaviour
|
||||||
{
|
{
|
||||||
public Camera MainCamera;
|
public Camera MainCamera;
|
||||||
@@ -33,3 +35,4 @@ public class Boot : MonoBehaviour
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,8 @@ using System.Collections.Generic;
|
|||||||
using System;
|
using System;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Tuan.GameFramework
|
||||||
|
{
|
||||||
public static class EventBus
|
public static class EventBus
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -86,3 +88,4 @@ public static class EventBus
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
namespace Tuan.GameFramework
|
||||||
|
{
|
||||||
public interface IEvent { }
|
public interface IEvent { }
|
||||||
|
|
||||||
public interface IEventHandler<TEvent> where TEvent : IEvent
|
public interface IEventHandler<TEvent> where TEvent : IEvent
|
||||||
@@ -25,3 +27,4 @@ public abstract class EventHandler<TEvent> : IEventHandler<TEvent> where TEvent
|
|||||||
|
|
||||||
protected abstract void OnEvent(TEvent eventData);
|
protected abstract void OnEvent(TEvent eventData);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,8 @@
|
|||||||
"GUID:e34a5702dd353724aa315fb8011f08c3",
|
"GUID:e34a5702dd353724aa315fb8011f08c3",
|
||||||
"GUID:f51ebe6a0ceec4240a699833d6309b23",
|
"GUID:f51ebe6a0ceec4240a699833d6309b23",
|
||||||
"GUID:3fe1a3e70da50184f9897101cad7e4f2",
|
"GUID:3fe1a3e70da50184f9897101cad7e4f2",
|
||||||
"GUID:13ba8ce62aa80c74598530029cb2d649"
|
"GUID:13ba8ce62aa80c74598530029cb2d649",
|
||||||
|
"GUID:928f8a513cd12e84cb0d3c0a21a84e2f"
|
||||||
],
|
],
|
||||||
"includePlatforms": [],
|
"includePlatforms": [],
|
||||||
"excludePlatforms": [],
|
"excludePlatforms": [],
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Tuan.GameFramework
|
||||||
|
{
|
||||||
public class GameManager : Singleton<GameManager>
|
public class GameManager : Singleton<GameManager>
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Tuan.GameFramework
|
||||||
|
{
|
||||||
public class MainUICanvas : SingletonMono<MainUICanvas>
|
public class MainUICanvas : SingletonMono<MainUICanvas>
|
||||||
{
|
{
|
||||||
public GameObject InitBg;
|
public GameObject InitBg;
|
||||||
@@ -13,3 +15,4 @@ public class MainUICanvas : SingletonMono<MainUICanvas>
|
|||||||
DontDestroyOnLoad(UICamera);
|
DontDestroyOnLoad(UICamera);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,8 @@ using UnityEngine.UI;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Tuan.GameFramework
|
||||||
|
{
|
||||||
public class MessageBox : MonoBehaviour
|
public class MessageBox : MonoBehaviour
|
||||||
{
|
{
|
||||||
[SerializeField] private GameObject panel;
|
[SerializeField] private GameObject panel;
|
||||||
@@ -84,3 +86,4 @@ public class MessageBox : MonoBehaviour
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
46
Assets/GameFramework/Runtime/Patch/HotDllLoader.cs
Normal file
46
Assets/GameFramework/Runtime/Patch/HotDllLoader.cs
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
using Cysharp.Threading.Tasks;
|
||||||
|
using HybridCLR;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using UnityEngine;
|
||||||
|
using YooAsset;
|
||||||
|
|
||||||
|
namespace Tuan.GameFramework
|
||||||
|
{
|
||||||
|
public class HotDllLoader : Singleton<HotDllLoader>
|
||||||
|
{
|
||||||
|
public List<string> DepDlls = new List<string>()
|
||||||
|
{
|
||||||
|
"mscorlib.dll",
|
||||||
|
"System.dll",
|
||||||
|
"System.Core.dll",
|
||||||
|
};
|
||||||
|
public async UniTask LoadDll(ResourcePackage package, string dll)
|
||||||
|
{
|
||||||
|
if (package.GetAssetInfo(dll).Error == string.Empty)
|
||||||
|
{
|
||||||
|
AssetHandle handle = package.LoadAssetAsync<TextAsset>(dll);
|
||||||
|
await handle.ToUniTask();
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
Assembly hotUpdateAss = System.AppDomain.CurrentDomain.GetAssemblies().First(a => a.GetName().Name == dll.Replace(".dll", ""));
|
||||||
|
#else
|
||||||
|
Assembly hotUpdateAss = Assembly.Load((handle.AssetObject as TextAsset).bytes);
|
||||||
|
#endif
|
||||||
|
Debug.Log($"加载{dll}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public async UniTask LoadDepDll(ResourcePackage package)
|
||||||
|
{
|
||||||
|
foreach (string dll in DepDlls)
|
||||||
|
{
|
||||||
|
if (package.GetAssetInfo(dll).Error == string.Empty)
|
||||||
|
{
|
||||||
|
AssetHandle handle = package.LoadAssetAsync<TextAsset>(dll);
|
||||||
|
await handle.ToUniTask();
|
||||||
|
RuntimeApi.LoadMetadataForAOTAssembly((handle.AssetObject as TextAsset).bytes, HomologousImageMode.SuperSet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
65
Assets/GameFramework/Runtime/Patch/MainOperation.cs
Normal file
65
Assets/GameFramework/Runtime/Patch/MainOperation.cs
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
using Cysharp.Threading.Tasks;
|
||||||
|
using YooAsset;
|
||||||
|
|
||||||
|
namespace Tuan.GameFramework
|
||||||
|
{
|
||||||
|
public class MainOperation
|
||||||
|
{
|
||||||
|
PatchOperationData data;
|
||||||
|
PatchOperation operation;
|
||||||
|
bool autoDownload;
|
||||||
|
public MainOperation(EPlayMode playMode, bool autoDownload = false)
|
||||||
|
{
|
||||||
|
data = new PatchOperationData();
|
||||||
|
data.packageName = "Main";
|
||||||
|
data.playMode = playMode;
|
||||||
|
data.useBuildinFileSystem = false;
|
||||||
|
data.downloadingMaxNum = 10;
|
||||||
|
data.failedTryAgain = 3;
|
||||||
|
data.downloadUpdate = OnDownloadUpdate;
|
||||||
|
data.downloadFinish = OnDownloadFinish;
|
||||||
|
data.downloadError = OnDownloadError;
|
||||||
|
|
||||||
|
operation = new PatchOperation(data);
|
||||||
|
this.autoDownload = autoDownload;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async UniTask Execute()
|
||||||
|
{
|
||||||
|
PatchEvent.UpdateProgress(0f);
|
||||||
|
if (!await operation.InitializePackage()) return;
|
||||||
|
if (!await operation.RequestPackageVersion()) return;
|
||||||
|
if (!await operation.UpdatePackageManifest()) return;
|
||||||
|
if (operation.CreateDownloader())
|
||||||
|
{
|
||||||
|
if (autoDownload)
|
||||||
|
{
|
||||||
|
if (!await operation.DownloadPackageFiles()) return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!await operation.CheckDownloadOrSkip()) return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!await operation.ClearCacheBundle()) return;
|
||||||
|
operation.SaveVersionToCache();
|
||||||
|
YooAssets.SetDefaultPackage(operation.package);
|
||||||
|
}
|
||||||
|
private void OnDownloadUpdate(DownloadUpdateData downloadUpdateData)
|
||||||
|
{
|
||||||
|
float progress = (float)downloadUpdateData.CurrentDownloadBytes / downloadUpdateData.TotalDownloadBytes;
|
||||||
|
string sizeText = $"{operation.FormatFileSize(downloadUpdateData.CurrentDownloadBytes)} / {operation.FormatFileSize(downloadUpdateData.TotalDownloadBytes)}";
|
||||||
|
PatchEvent.UpdateProgress(progress);
|
||||||
|
PatchEvent.UpdateDownloadSize(sizeText);
|
||||||
|
PatchEvent.UpdateStatus($"{data.packageName} 资源下载中...");
|
||||||
|
}
|
||||||
|
private void OnDownloadFinish(DownloaderFinishData downloaderFinishData)
|
||||||
|
{
|
||||||
|
PatchEvent.UpdateStatus("下载完成");
|
||||||
|
}
|
||||||
|
private void OnDownloadError(DownloadErrorData downloadErrorData)
|
||||||
|
{
|
||||||
|
PatchEvent.UpdateStatus($"下载失败:{downloadErrorData.FileName}\n{downloadErrorData.ErrorInfo}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
31
Assets/GameFramework/Runtime/Patch/PatchEvent.cs
Normal file
31
Assets/GameFramework/Runtime/Patch/PatchEvent.cs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Tuan.GameFramework
|
||||||
|
{
|
||||||
|
public static class PatchEvent
|
||||||
|
{
|
||||||
|
public static event Action<string> OnStatusUpdate;
|
||||||
|
public static event Action<float> OnProgressUpdate;
|
||||||
|
public static event Action<string> OnDownloadSizeUpdate;
|
||||||
|
public static event Action OnClosePatchWindow;
|
||||||
|
|
||||||
|
public static void UpdateStatus(string status)
|
||||||
|
{
|
||||||
|
OnStatusUpdate?.Invoke(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UpdateProgress(float progress)
|
||||||
|
{
|
||||||
|
OnProgressUpdate?.Invoke(progress);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UpdateDownloadSize(string sizeText)
|
||||||
|
{
|
||||||
|
OnDownloadSizeUpdate?.Invoke(sizeText);
|
||||||
|
}
|
||||||
|
public static void ClosePatchWindow()
|
||||||
|
{
|
||||||
|
OnClosePatchWindow?.Invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
22
Assets/GameFramework/Runtime/Patch/PatchManager.cs
Normal file
22
Assets/GameFramework/Runtime/Patch/PatchManager.cs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
using Cysharp.Threading.Tasks;
|
||||||
|
using YooAsset;
|
||||||
|
|
||||||
|
namespace Tuan.GameFramework
|
||||||
|
{
|
||||||
|
public class PatchManager : Singleton<PatchManager>
|
||||||
|
{
|
||||||
|
public async UniTask<bool> StartOperation(EPlayMode playMode)
|
||||||
|
{
|
||||||
|
YooAssets.Initialize();
|
||||||
|
PreloadOperation _preloadOperation = new PreloadOperation(playMode);
|
||||||
|
await _preloadOperation.Execute();
|
||||||
|
|
||||||
|
MainOperation _mainOperation = new MainOperation(playMode);
|
||||||
|
await _mainOperation.Execute();
|
||||||
|
await HotDllLoader.Inst.LoadDepDll(YooAssets.GetPackage("Main"));
|
||||||
|
await HotDllLoader.Inst.LoadDll(YooAssets.GetPackage("Main"), "GameScripts.Main");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
362
Assets/GameFramework/Runtime/Patch/PatchOperation.cs
Normal file
362
Assets/GameFramework/Runtime/Patch/PatchOperation.cs
Normal file
@@ -0,0 +1,362 @@
|
|||||||
|
using Cysharp.Threading.Tasks;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
using YooAsset;
|
||||||
|
using static YooAsset.DownloaderOperation;
|
||||||
|
|
||||||
|
namespace Tuan.GameFramework
|
||||||
|
{
|
||||||
|
public class PatchOperationData
|
||||||
|
{
|
||||||
|
public string packageName;
|
||||||
|
public EPlayMode playMode;
|
||||||
|
public bool useBuildinFileSystem;
|
||||||
|
public DownloadError downloadError;
|
||||||
|
public DownloaderFinish downloadFinish;
|
||||||
|
public DownloadUpdate downloadUpdate;
|
||||||
|
public int downloadingMaxNum = 10;
|
||||||
|
public int failedTryAgain = 3;
|
||||||
|
}
|
||||||
|
public class PatchOperation
|
||||||
|
{
|
||||||
|
public PatchOperationData data;
|
||||||
|
public ResourcePackage package;
|
||||||
|
public ResourceDownloaderOperation downloader;
|
||||||
|
public string packageVersion;
|
||||||
|
public string PkgVersionKey;
|
||||||
|
public PatchOperation(PatchOperationData data)
|
||||||
|
{
|
||||||
|
this.data = data;
|
||||||
|
PkgVersionKey = $"{Application.productName}_{data.packageName}";
|
||||||
|
#if !UNITY_EDITOR
|
||||||
|
PkgVersionKey = $"Editor_{Application.productName}_{data.packageName}";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#region 初始化相关
|
||||||
|
public async UniTask<bool> InitializePackage()
|
||||||
|
{
|
||||||
|
package = YooAssets.TryGetPackage(data.packageName);
|
||||||
|
if (package == null)
|
||||||
|
package = YooAssets.CreatePackage(data.packageName);
|
||||||
|
|
||||||
|
InitializationOperation initializationOperation = null;
|
||||||
|
switch (data.playMode)
|
||||||
|
{
|
||||||
|
case EPlayMode.EditorSimulateMode:
|
||||||
|
initializationOperation = InitializeEditorMode(package);
|
||||||
|
break;
|
||||||
|
case EPlayMode.OfflinePlayMode:
|
||||||
|
initializationOperation = InitializeOfflineMode(package);
|
||||||
|
break;
|
||||||
|
case EPlayMode.HostPlayMode:
|
||||||
|
initializationOperation = InitializeHostMode(package);
|
||||||
|
break;
|
||||||
|
case EPlayMode.WebPlayMode:
|
||||||
|
initializationOperation = InitializeWebPlayMode(package);
|
||||||
|
break;
|
||||||
|
case EPlayMode.CustomPlayMode:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
await initializationOperation.ToUniTask();
|
||||||
|
if (initializationOperation.Status != EOperationStatus.Succeed)
|
||||||
|
{
|
||||||
|
MessageBox.Show()
|
||||||
|
.SetTitle($"{data.packageName}初始化")
|
||||||
|
.SetContent($"{initializationOperation.Error}")
|
||||||
|
.AddButton("退出", (box) => { Application.Quit(); });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PatchEvent.UpdateStatus($"初始化成功{data.packageName}");
|
||||||
|
Debug.Log($"初始化成功{data.packageName}");
|
||||||
|
}
|
||||||
|
return initializationOperation.Status == EOperationStatus.Succeed;
|
||||||
|
}
|
||||||
|
private InitializationOperation InitializeEditorMode(ResourcePackage package)
|
||||||
|
{
|
||||||
|
var buildResult = EditorSimulateModeHelper.SimulateBuild(data.packageName);
|
||||||
|
var packageRoot = buildResult.PackageRootDirectory;
|
||||||
|
var createParameters = new EditorSimulateModeParameters();
|
||||||
|
createParameters.EditorFileSystemParameters = FileSystemParameters.CreateDefaultEditorFileSystemParameters(packageRoot);
|
||||||
|
return package.InitializeAsync(createParameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
private InitializationOperation InitializeOfflineMode(ResourcePackage package)
|
||||||
|
{
|
||||||
|
var createParameters = new OfflinePlayModeParameters();
|
||||||
|
createParameters.BuildinFileSystemParameters = FileSystemParameters.CreateDefaultBuildinFileSystemParameters();
|
||||||
|
return package.InitializeAsync(createParameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
private InitializationOperation InitializeHostMode(ResourcePackage package)
|
||||||
|
{
|
||||||
|
FileSystemParameters buildinFileSystemParams = null;
|
||||||
|
if (data.useBuildinFileSystem)
|
||||||
|
{
|
||||||
|
// 注意:设置参数COPY_BUILDIN_PACKAGE_MANIFEST,可以初始化的时候拷贝内置清单到沙盒目录
|
||||||
|
buildinFileSystemParams = FileSystemParameters.CreateDefaultBuildinFileSystemParameters();
|
||||||
|
buildinFileSystemParams.AddParameter(FileSystemParametersDefine.COPY_BUILDIN_PACKAGE_MANIFEST, true);
|
||||||
|
}
|
||||||
|
string defaultHostServer = GetHostServerURL();
|
||||||
|
string fallbackHostServer = GetHostServerURL();
|
||||||
|
IRemoteServices remoteServices = new RemoteServices(defaultHostServer, fallbackHostServer);
|
||||||
|
// 注意:设置参数INSTALL_CLEAR_MODE,可以解决覆盖安装的时候将拷贝的内置清单文件清理的问题。
|
||||||
|
var cacheFileSystemParams = FileSystemParameters.CreateDefaultCacheFileSystemParameters(remoteServices);
|
||||||
|
cacheFileSystemParams.AddParameter(FileSystemParametersDefine.INSTALL_CLEAR_MODE, EOverwriteInstallClearMode.ClearAllManifestFiles);
|
||||||
|
|
||||||
|
var createParameters = new HostPlayModeParameters();
|
||||||
|
createParameters.BuildinFileSystemParameters = buildinFileSystemParams;
|
||||||
|
createParameters.CacheFileSystemParameters = cacheFileSystemParams;
|
||||||
|
return package.InitializeAsync(createParameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
private InitializationOperation InitializeWebPlayMode(ResourcePackage package)
|
||||||
|
{
|
||||||
|
#if UNITY_WEBGL && WEIXINMINIGAME && !UNITY_EDITOR
|
||||||
|
var createParameters = new WebPlayModeParameters();
|
||||||
|
string defaultHostServer = GetHostServerURL();
|
||||||
|
string fallbackHostServer = GetHostServerURL();
|
||||||
|
string packageRoot = $"{WeChatWASM.WX.env.USER_DATA_PATH}/__GAME_FILE_CACHE"; //注意:如果有子目录,请修改此处!
|
||||||
|
IRemoteServices remoteServices = new RemoteServices(defaultHostServer, fallbackHostServer);
|
||||||
|
createParameters.WebServerFileSystemParameters = WechatFileSystemCreater.CreateFileSystemParameters(packageRoot, remoteServices);
|
||||||
|
return package.InitializeAsync(createParameters);
|
||||||
|
#else
|
||||||
|
var createParameters = new WebPlayModeParameters();
|
||||||
|
createParameters.WebServerFileSystemParameters = FileSystemParameters.CreateDefaultWebServerFileSystemParameters();
|
||||||
|
return package.InitializeAsync(createParameters);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
private string GetHostServerURL()
|
||||||
|
{
|
||||||
|
string hostServerIP = $"https://home.gtuantuan.online:9444/{Application.productName}";
|
||||||
|
string appVersion = "v1";
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
if (UnityEditor.EditorUserBuildSettings.activeBuildTarget == UnityEditor.BuildTarget.Android)
|
||||||
|
// return $"{hostServerIP}/CDN/Android/{packageName}/{appVersion}";
|
||||||
|
return $"{hostServerIP}/CDN/PC/{data.packageName}/{appVersion}";
|
||||||
|
else if (UnityEditor.EditorUserBuildSettings.activeBuildTarget == UnityEditor.BuildTarget.iOS)
|
||||||
|
return $"{hostServerIP}/CDN/IPhone/{data.packageName}/{appVersion}";
|
||||||
|
else if (UnityEditor.EditorUserBuildSettings.activeBuildTarget == UnityEditor.BuildTarget.WebGL)
|
||||||
|
return $"{hostServerIP}/CDN/WebGL/{data.packageName}/{appVersion}";
|
||||||
|
else
|
||||||
|
return $"{hostServerIP}/CDN/PC/{data.packageName}/{appVersion}";
|
||||||
|
#else
|
||||||
|
if (Application.platform == RuntimePlatform.Android)
|
||||||
|
return $"{hostServerIP}/CDN/Android/{data.packageName}/{appVersion}";
|
||||||
|
else if (Application.platform == RuntimePlatform.IPhonePlayer)
|
||||||
|
return $"{hostServerIP}/CDN/IPhone/{data.packageName}/{appVersion}";
|
||||||
|
else if (Application.platform == RuntimePlatform.WebGLPlayer)
|
||||||
|
return $"{hostServerIP}/CDN/WebGL/{data.packageName}/{appVersion}";
|
||||||
|
else
|
||||||
|
return $"{hostServerIP}/CDN/PC/{data.packageName}/{appVersion}";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
private class RemoteServices : IRemoteServices
|
||||||
|
{
|
||||||
|
private readonly string _defaultHostServer;
|
||||||
|
private readonly string _fallbackHostServer;
|
||||||
|
|
||||||
|
public RemoteServices(string defaultHostServer, string fallbackHostServer)
|
||||||
|
{
|
||||||
|
_defaultHostServer = defaultHostServer;
|
||||||
|
_fallbackHostServer = fallbackHostServer;
|
||||||
|
}
|
||||||
|
string IRemoteServices.GetRemoteMainURL(string fileName)
|
||||||
|
{
|
||||||
|
return $"{_defaultHostServer}/{fileName}";
|
||||||
|
}
|
||||||
|
string IRemoteServices.GetRemoteFallbackURL(string fileName)
|
||||||
|
{
|
||||||
|
return $"{_fallbackHostServer}/{fileName}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
#region 版本和资源清单相关
|
||||||
|
public async UniTask<bool> RequestPackageVersion(bool showBox = true)
|
||||||
|
{
|
||||||
|
var operation = package.RequestPackageVersionAsync(true, 5);
|
||||||
|
await operation.ToUniTask();
|
||||||
|
if (operation.Status != EOperationStatus.Succeed)
|
||||||
|
{
|
||||||
|
if (showBox)
|
||||||
|
{
|
||||||
|
if (await CheckUseLocalVersion(operation))
|
||||||
|
{
|
||||||
|
string cachedVersion = GetCachedPackageVersion();
|
||||||
|
if (!string.IsNullOrEmpty(cachedVersion))
|
||||||
|
{
|
||||||
|
packageVersion = cachedVersion;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
packageVersion = operation.PackageVersion;
|
||||||
|
PatchEvent.UpdateStatus($"获取版本成功{data.packageName}");
|
||||||
|
Debug.Log($"获取版本成功{data.packageName}:{packageVersion}");
|
||||||
|
}
|
||||||
|
return operation.Status == EOperationStatus.Succeed;
|
||||||
|
}
|
||||||
|
public async UniTask<bool> CheckUseLocalVersion(RequestPackageVersionOperation operation)
|
||||||
|
{
|
||||||
|
var completionSource = new UniTaskCompletionSource<bool>();
|
||||||
|
MessageBox.Show()
|
||||||
|
.SetTitle($"{data.packageName}请求版本")
|
||||||
|
.SetContent($"{operation.Error}")
|
||||||
|
.AddButton("继续", (box) =>
|
||||||
|
{
|
||||||
|
completionSource.TrySetResult(true);
|
||||||
|
})
|
||||||
|
.AddButton("退出", (box) =>
|
||||||
|
{
|
||||||
|
completionSource.TrySetResult(false);
|
||||||
|
Application.Quit();
|
||||||
|
});
|
||||||
|
bool shouldContinue = await completionSource.Task;
|
||||||
|
return shouldContinue;
|
||||||
|
}
|
||||||
|
public async Task<string> GetBuildinPackageVersion()
|
||||||
|
{
|
||||||
|
var operation = new GetBuildinPackageVersionOperation(data.packageName);
|
||||||
|
YooAssets.StartOperation(operation);
|
||||||
|
await operation;
|
||||||
|
if (operation.Status == EOperationStatus.Succeed)
|
||||||
|
{
|
||||||
|
return operation.PackageVersion;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public string GetCachedPackageVersion()
|
||||||
|
{
|
||||||
|
if (PlayerPrefs.HasKey(PkgVersionKey))
|
||||||
|
{
|
||||||
|
return PlayerPrefs.GetString(PkgVersionKey);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SaveVersionToCache()
|
||||||
|
{
|
||||||
|
PlayerPrefs.SetString(PkgVersionKey, packageVersion);
|
||||||
|
PlayerPrefs.Save();
|
||||||
|
PatchEvent.UpdateStatus($"更新完成{data.packageName}");
|
||||||
|
Debug.Log($"更新{data.packageName}完成,版本号{packageVersion}");
|
||||||
|
|
||||||
|
}
|
||||||
|
public async UniTask<bool> UpdatePackageManifest(bool showBox = true)
|
||||||
|
{
|
||||||
|
var operation = package.UpdatePackageManifestAsync(packageVersion, 10);
|
||||||
|
await operation.ToUniTask();
|
||||||
|
if (operation.Status != EOperationStatus.Succeed)
|
||||||
|
{
|
||||||
|
if (showBox)
|
||||||
|
{
|
||||||
|
MessageBox.Show()
|
||||||
|
.SetTitle($"{data.packageName}更新清单")
|
||||||
|
.SetContent($"{operation.Error}")
|
||||||
|
.AddButton("退出", (box) => { Application.Quit(); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PatchEvent.UpdateStatus($"获取资源清单成功{data.packageName}");
|
||||||
|
Debug.Log($"获取资源清单成功{data.packageName}");
|
||||||
|
}
|
||||||
|
return operation.Status == EOperationStatus.Succeed;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
#region 下载相关
|
||||||
|
public bool CreateDownloader()
|
||||||
|
{
|
||||||
|
downloader = package.CreateResourceDownloader(data.downloadingMaxNum, data.failedTryAgain);
|
||||||
|
downloader.DownloadErrorCallback = data.downloadError;
|
||||||
|
downloader.DownloadFinishCallback = data.downloadFinish;
|
||||||
|
downloader.DownloadUpdateCallback = data.downloadUpdate;
|
||||||
|
if (downloader.TotalDownloadCount == 0) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public async UniTask<bool> CheckDownloadOrSkip()
|
||||||
|
{
|
||||||
|
var completionSource = new UniTaskCompletionSource<bool>();
|
||||||
|
MessageBox.Show()
|
||||||
|
.SetTitle($"{data.packageName}发现更新")
|
||||||
|
.SetContent($"发现资源更新\n{GetCachedPackageVersion()}=>{packageVersion}: {FormatFileSize(downloader.TotalDownloadBytes)}")
|
||||||
|
.AddButton("下载", async (box) =>
|
||||||
|
{
|
||||||
|
bool success = await DownloadPackageFiles();
|
||||||
|
completionSource.TrySetResult(success);
|
||||||
|
})
|
||||||
|
.AddButton("跳过", async (box) =>
|
||||||
|
{
|
||||||
|
downloader.CancelDownload();
|
||||||
|
packageVersion = GetCachedPackageVersion();
|
||||||
|
await UpdatePackageManifest();
|
||||||
|
completionSource.TrySetResult(true);
|
||||||
|
})
|
||||||
|
.AddButton("退出", (box) =>
|
||||||
|
{
|
||||||
|
downloader.CancelDownload();
|
||||||
|
completionSource.TrySetResult(false);
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
UnityEditor.EditorApplication.isPlaying = false;
|
||||||
|
#else
|
||||||
|
Application.Quit();
|
||||||
|
#endif
|
||||||
|
});
|
||||||
|
bool shouldContinue = await completionSource.Task;
|
||||||
|
return shouldContinue;
|
||||||
|
}
|
||||||
|
public async UniTask<bool> DownloadPackageFiles(bool showBox = true)
|
||||||
|
{
|
||||||
|
if (downloader.TotalDownloadCount == 0)
|
||||||
|
return true;
|
||||||
|
Debug.Log($"{data.packageName} DownloadPackageFiles {downloader.TotalDownloadCount}");
|
||||||
|
downloader.BeginDownload();
|
||||||
|
await downloader.ToUniTask();
|
||||||
|
if (downloader.Status != EOperationStatus.Succeed)
|
||||||
|
{
|
||||||
|
if (showBox)
|
||||||
|
{
|
||||||
|
MessageBox.Show()
|
||||||
|
.SetTitle($"{data.packageName}下载文件")
|
||||||
|
.SetContent($"{downloader.Error}")
|
||||||
|
.AddButton("退出", (box) => { Application.Quit(); });
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return downloader.Status == EOperationStatus.Succeed;
|
||||||
|
}
|
||||||
|
public async UniTask<bool> ClearCacheBundle(bool showBox = true)
|
||||||
|
{
|
||||||
|
var operation = package.ClearCacheFilesAsync(EFileClearMode.ClearUnusedBundleFiles);
|
||||||
|
await operation.ToUniTask();
|
||||||
|
if (operation.Status != EOperationStatus.Succeed)
|
||||||
|
{
|
||||||
|
if (showBox)
|
||||||
|
{
|
||||||
|
MessageBox.Show()
|
||||||
|
.SetTitle($"{data.packageName}清除缓存")
|
||||||
|
.SetContent($"{operation.Error}")
|
||||||
|
.AddButton("退出", (box) => { Application.Quit(); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return operation.Status == EOperationStatus.Succeed;
|
||||||
|
}
|
||||||
|
public string FormatFileSize(long size)
|
||||||
|
{
|
||||||
|
if (size < 1024 * 1024)
|
||||||
|
return $"{(size / 1024f):F1}KB";
|
||||||
|
else
|
||||||
|
return $"{size / 1024f / 1024f:F1}MB";
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
91
Assets/GameFramework/Runtime/Patch/PreloadOperation.cs
Normal file
91
Assets/GameFramework/Runtime/Patch/PreloadOperation.cs
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
using Cysharp.Threading.Tasks;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
using YooAsset;
|
||||||
|
|
||||||
|
namespace Tuan.GameFramework
|
||||||
|
{
|
||||||
|
public class PreloadOperation
|
||||||
|
{
|
||||||
|
PatchOperationData data;
|
||||||
|
PatchOperation operation;
|
||||||
|
public PreloadOperation(EPlayMode playMode)
|
||||||
|
{
|
||||||
|
data = new PatchOperationData();
|
||||||
|
data.packageName = "Preload";
|
||||||
|
data.playMode = playMode;
|
||||||
|
data.useBuildinFileSystem = true;
|
||||||
|
data.downloadingMaxNum = 10;
|
||||||
|
data.failedTryAgain = 3;
|
||||||
|
|
||||||
|
operation = new PatchOperation(data);
|
||||||
|
}
|
||||||
|
public async UniTask Execute()
|
||||||
|
{
|
||||||
|
#if !UNITY_EDITOR
|
||||||
|
CheckIsOffline();
|
||||||
|
#endif
|
||||||
|
if (!await operation.InitializePackage()) return;
|
||||||
|
var version = await GetBestPackageVersion();
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
if (!await operation.RequestPackageVersion()) return;
|
||||||
|
version = operation.packageVersion;
|
||||||
|
#endif
|
||||||
|
//获取版本失败
|
||||||
|
if (version == null)
|
||||||
|
{
|
||||||
|
MessageBox.Show()
|
||||||
|
.SetTitle($"{operation.data.packageName}获取版本")
|
||||||
|
.SetContent("获取版本失败")
|
||||||
|
.AddButton("退出", (box) => { Application.Quit(); });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
operation.packageVersion = version;
|
||||||
|
if (!await operation.UpdatePackageManifest()) return;
|
||||||
|
await HotDllLoader.Inst.LoadDll(YooAssets.GetPackage("Preload"), "GameScripts.Preload");
|
||||||
|
await LoadAndShowPatchWindow();
|
||||||
|
MainUICanvas.Inst.InitBg.SetActive(false);
|
||||||
|
_ = UpdatePreloadPackage();
|
||||||
|
}
|
||||||
|
void CheckIsOffline()
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(operation.GetCachedPackageVersion()))
|
||||||
|
{
|
||||||
|
operation.data.playMode = EPlayMode.OfflinePlayMode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async Task<string> GetBestPackageVersion()
|
||||||
|
{
|
||||||
|
string cachedVersion = operation.GetCachedPackageVersion();
|
||||||
|
if (!string.IsNullOrEmpty(cachedVersion))
|
||||||
|
{
|
||||||
|
return cachedVersion;
|
||||||
|
}
|
||||||
|
string buildinVersion = await operation.GetBuildinPackageVersion();
|
||||||
|
if (!string.IsNullOrEmpty(buildinVersion))
|
||||||
|
{
|
||||||
|
return buildinVersion;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
private async UniTask LoadAndShowPatchWindow()
|
||||||
|
{
|
||||||
|
var assetHandle = operation.package.LoadAssetAsync<GameObject>("PatchWindow");
|
||||||
|
await assetHandle.ToUniTask();
|
||||||
|
if (assetHandle.Status == EOperationStatus.Succeed)
|
||||||
|
GameObject.Instantiate(assetHandle.AssetObject, MainUICanvas.Inst.Medium);
|
||||||
|
Debug.Log("创建热更信息界面");
|
||||||
|
}
|
||||||
|
private async UniTask UpdatePreloadPackage()
|
||||||
|
{
|
||||||
|
if (!await operation.RequestPackageVersion(false)) return;
|
||||||
|
if (!await operation.UpdatePackageManifest(false)) return;
|
||||||
|
if (operation.CreateDownloader())
|
||||||
|
{
|
||||||
|
if (!await operation.DownloadPackageFiles()) return;
|
||||||
|
}
|
||||||
|
if (!await operation.ClearCacheBundle()) return;
|
||||||
|
operation.SaveVersionToCache();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
using Cysharp.Threading.Tasks;
|
|
||||||
using HybridCLR;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using UnityEngine;
|
|
||||||
using YooAsset;
|
|
||||||
|
|
||||||
public class HotDllLoader : Singleton<HotDllLoader>
|
|
||||||
{
|
|
||||||
public List<string> DepDlls = new List<string>()
|
|
||||||
{
|
|
||||||
"mscorlib.dll",
|
|
||||||
"System.dll",
|
|
||||||
"System.Core.dll",
|
|
||||||
};
|
|
||||||
public async UniTask LoadDll(ResourcePackage package, string dll)
|
|
||||||
{
|
|
||||||
if (package.GetAssetInfo(dll).Error == string.Empty)
|
|
||||||
{
|
|
||||||
AssetHandle handle = package.LoadAssetAsync<TextAsset>(dll);
|
|
||||||
await handle.ToUniTask();
|
|
||||||
#if UNITY_EDITOR
|
|
||||||
Assembly hotUpdateAss = System.AppDomain.CurrentDomain.GetAssemblies().First(a => a.GetName().Name == dll.Replace(".dll", ""));
|
|
||||||
#else
|
|
||||||
Assembly hotUpdateAss = Assembly.Load((handle.AssetObject as TextAsset).bytes);
|
|
||||||
#endif
|
|
||||||
Debug.Log($"加载{dll}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public async UniTask LoadDepDll(ResourcePackage package)
|
|
||||||
{
|
|
||||||
foreach (string dll in DepDlls)
|
|
||||||
{
|
|
||||||
if (package.GetAssetInfo(dll).Error == string.Empty)
|
|
||||||
{
|
|
||||||
AssetHandle handle = package.LoadAssetAsync<TextAsset>(dll);
|
|
||||||
await handle.ToUniTask();
|
|
||||||
RuntimeApi.LoadMetadataForAOTAssembly((handle.AssetObject as TextAsset).bytes, HomologousImageMode.SuperSet);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
using Cysharp.Threading.Tasks;
|
|
||||||
using YooAsset;
|
|
||||||
|
|
||||||
public class MainOperation
|
|
||||||
{
|
|
||||||
PatchOperationData data;
|
|
||||||
PatchOperation operation;
|
|
||||||
bool autoDownload;
|
|
||||||
public MainOperation(EPlayMode playMode, bool autoDownload = false)
|
|
||||||
{
|
|
||||||
data = new PatchOperationData();
|
|
||||||
data.packageName = "Main";
|
|
||||||
data.playMode = playMode;
|
|
||||||
data.useBuildinFileSystem = false;
|
|
||||||
data.downloadingMaxNum = 10;
|
|
||||||
data.failedTryAgain = 3;
|
|
||||||
data.downloadUpdate = OnDownloadUpdate;
|
|
||||||
data.downloadFinish = OnDownloadFinish;
|
|
||||||
data.downloadError = OnDownloadError;
|
|
||||||
|
|
||||||
operation = new PatchOperation(data);
|
|
||||||
this.autoDownload = autoDownload;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async UniTask Execute()
|
|
||||||
{
|
|
||||||
PatchEvent.UpdateProgress(0f);
|
|
||||||
if (!await operation.InitializePackage()) return;
|
|
||||||
if (!await operation.RequestPackageVersion()) return;
|
|
||||||
if (!await operation.UpdatePackageManifest()) return;
|
|
||||||
if (operation.CreateDownloader())
|
|
||||||
{
|
|
||||||
if (autoDownload)
|
|
||||||
{
|
|
||||||
if (!await operation.DownloadPackageFiles()) return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!await operation.CheckDownloadOrSkip()) return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!await operation.ClearCacheBundle()) return;
|
|
||||||
operation.SaveVersionToCache();
|
|
||||||
YooAssets.SetDefaultPackage(operation.package);
|
|
||||||
}
|
|
||||||
private void OnDownloadUpdate(DownloadUpdateData downloadUpdateData)
|
|
||||||
{
|
|
||||||
float progress = (float)downloadUpdateData.CurrentDownloadBytes / downloadUpdateData.TotalDownloadBytes;
|
|
||||||
string sizeText = $"{operation.FormatFileSize(downloadUpdateData.CurrentDownloadBytes)} / {operation.FormatFileSize(downloadUpdateData.TotalDownloadBytes)}";
|
|
||||||
PatchEvent.UpdateProgress(progress);
|
|
||||||
PatchEvent.UpdateDownloadSize(sizeText);
|
|
||||||
PatchEvent.UpdateStatus($"{data.packageName} 资源下载中...");
|
|
||||||
}
|
|
||||||
private void OnDownloadFinish(DownloaderFinishData downloaderFinishData)
|
|
||||||
{
|
|
||||||
PatchEvent.UpdateStatus("下载完成");
|
|
||||||
}
|
|
||||||
private void OnDownloadError(DownloadErrorData downloadErrorData)
|
|
||||||
{
|
|
||||||
PatchEvent.UpdateStatus($"下载失败:{downloadErrorData.FileName}\n{downloadErrorData.ErrorInfo}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
public static class PatchEvent
|
|
||||||
{
|
|
||||||
public static event Action<string> OnStatusUpdate;
|
|
||||||
public static event Action<float> OnProgressUpdate;
|
|
||||||
public static event Action<string> OnDownloadSizeUpdate;
|
|
||||||
public static event Action OnClosePatchWindow;
|
|
||||||
|
|
||||||
public static void UpdateStatus(string status)
|
|
||||||
{
|
|
||||||
OnStatusUpdate?.Invoke(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void UpdateProgress(float progress)
|
|
||||||
{
|
|
||||||
OnProgressUpdate?.Invoke(progress);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void UpdateDownloadSize(string sizeText)
|
|
||||||
{
|
|
||||||
OnDownloadSizeUpdate?.Invoke(sizeText);
|
|
||||||
}
|
|
||||||
public static void ClosePatchWindow()
|
|
||||||
{
|
|
||||||
OnClosePatchWindow?.Invoke();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
using Cysharp.Threading.Tasks;
|
|
||||||
using YooAsset;
|
|
||||||
public class PatchManager : Singleton<PatchManager>
|
|
||||||
{
|
|
||||||
public async UniTask<bool> StartOperation(EPlayMode playMode)
|
|
||||||
{
|
|
||||||
YooAssets.Initialize();
|
|
||||||
PreloadOperation _preloadOperation = new PreloadOperation(playMode);
|
|
||||||
await _preloadOperation.Execute();
|
|
||||||
|
|
||||||
MainOperation _mainOperation = new MainOperation(playMode);
|
|
||||||
await _mainOperation.Execute();
|
|
||||||
await HotDllLoader.Inst.LoadDepDll(YooAssets.GetPackage("Main"));
|
|
||||||
await HotDllLoader.Inst.LoadDll(YooAssets.GetPackage("Main"), "GameScripts.Main");
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,358 +0,0 @@
|
|||||||
using Cysharp.Threading.Tasks;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using UnityEngine;
|
|
||||||
using YooAsset;
|
|
||||||
using static YooAsset.DownloaderOperation;
|
|
||||||
public class PatchOperationData
|
|
||||||
{
|
|
||||||
public string packageName;
|
|
||||||
public EPlayMode playMode;
|
|
||||||
public bool useBuildinFileSystem;
|
|
||||||
public DownloadError downloadError;
|
|
||||||
public DownloaderFinish downloadFinish;
|
|
||||||
public DownloadUpdate downloadUpdate;
|
|
||||||
public int downloadingMaxNum = 10;
|
|
||||||
public int failedTryAgain = 3;
|
|
||||||
}
|
|
||||||
public class PatchOperation
|
|
||||||
{
|
|
||||||
public PatchOperationData data;
|
|
||||||
public ResourcePackage package;
|
|
||||||
public ResourceDownloaderOperation downloader;
|
|
||||||
public string packageVersion;
|
|
||||||
public string PkgVersionKey;
|
|
||||||
public PatchOperation(PatchOperationData data)
|
|
||||||
{
|
|
||||||
this.data = data;
|
|
||||||
PkgVersionKey = $"{Application.productName}_{data.packageName}";
|
|
||||||
#if !UNITY_EDITOR
|
|
||||||
PkgVersionKey = $"Editor_{Application.productName}_{data.packageName}";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#region 初始化相关
|
|
||||||
public async UniTask<bool> InitializePackage()
|
|
||||||
{
|
|
||||||
package = YooAssets.TryGetPackage(data.packageName);
|
|
||||||
if (package == null)
|
|
||||||
package = YooAssets.CreatePackage(data.packageName);
|
|
||||||
|
|
||||||
InitializationOperation initializationOperation = null;
|
|
||||||
switch (data.playMode)
|
|
||||||
{
|
|
||||||
case EPlayMode.EditorSimulateMode:
|
|
||||||
initializationOperation = InitializeEditorMode(package);
|
|
||||||
break;
|
|
||||||
case EPlayMode.OfflinePlayMode:
|
|
||||||
initializationOperation = InitializeOfflineMode(package);
|
|
||||||
break;
|
|
||||||
case EPlayMode.HostPlayMode:
|
|
||||||
initializationOperation = InitializeHostMode(package);
|
|
||||||
break;
|
|
||||||
case EPlayMode.WebPlayMode:
|
|
||||||
initializationOperation = InitializeWebPlayMode(package);
|
|
||||||
break;
|
|
||||||
case EPlayMode.CustomPlayMode:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
await initializationOperation.ToUniTask();
|
|
||||||
if (initializationOperation.Status != EOperationStatus.Succeed)
|
|
||||||
{
|
|
||||||
MessageBox.Show()
|
|
||||||
.SetTitle($"{data.packageName}初始化")
|
|
||||||
.SetContent($"{initializationOperation.Error}")
|
|
||||||
.AddButton("退出", (box) => { Application.Quit(); });
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PatchEvent.UpdateStatus($"初始化成功{data.packageName}");
|
|
||||||
Debug.Log($"初始化成功{data.packageName}");
|
|
||||||
}
|
|
||||||
return initializationOperation.Status == EOperationStatus.Succeed;
|
|
||||||
}
|
|
||||||
private InitializationOperation InitializeEditorMode(ResourcePackage package)
|
|
||||||
{
|
|
||||||
var buildResult = EditorSimulateModeHelper.SimulateBuild(data.packageName);
|
|
||||||
var packageRoot = buildResult.PackageRootDirectory;
|
|
||||||
var createParameters = new EditorSimulateModeParameters();
|
|
||||||
createParameters.EditorFileSystemParameters = FileSystemParameters.CreateDefaultEditorFileSystemParameters(packageRoot);
|
|
||||||
return package.InitializeAsync(createParameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
private InitializationOperation InitializeOfflineMode(ResourcePackage package)
|
|
||||||
{
|
|
||||||
var createParameters = new OfflinePlayModeParameters();
|
|
||||||
createParameters.BuildinFileSystemParameters = FileSystemParameters.CreateDefaultBuildinFileSystemParameters();
|
|
||||||
return package.InitializeAsync(createParameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
private InitializationOperation InitializeHostMode(ResourcePackage package)
|
|
||||||
{
|
|
||||||
FileSystemParameters buildinFileSystemParams = null;
|
|
||||||
if (data.useBuildinFileSystem)
|
|
||||||
{
|
|
||||||
// 注意:设置参数COPY_BUILDIN_PACKAGE_MANIFEST,可以初始化的时候拷贝内置清单到沙盒目录
|
|
||||||
buildinFileSystemParams = FileSystemParameters.CreateDefaultBuildinFileSystemParameters();
|
|
||||||
buildinFileSystemParams.AddParameter(FileSystemParametersDefine.COPY_BUILDIN_PACKAGE_MANIFEST, true);
|
|
||||||
}
|
|
||||||
string defaultHostServer = GetHostServerURL();
|
|
||||||
string fallbackHostServer = GetHostServerURL();
|
|
||||||
IRemoteServices remoteServices = new RemoteServices(defaultHostServer, fallbackHostServer);
|
|
||||||
// 注意:设置参数INSTALL_CLEAR_MODE,可以解决覆盖安装的时候将拷贝的内置清单文件清理的问题。
|
|
||||||
var cacheFileSystemParams = FileSystemParameters.CreateDefaultCacheFileSystemParameters(remoteServices);
|
|
||||||
cacheFileSystemParams.AddParameter(FileSystemParametersDefine.INSTALL_CLEAR_MODE, EOverwriteInstallClearMode.ClearAllManifestFiles);
|
|
||||||
|
|
||||||
var createParameters = new HostPlayModeParameters();
|
|
||||||
createParameters.BuildinFileSystemParameters = buildinFileSystemParams;
|
|
||||||
createParameters.CacheFileSystemParameters = cacheFileSystemParams;
|
|
||||||
return package.InitializeAsync(createParameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
private InitializationOperation InitializeWebPlayMode(ResourcePackage package)
|
|
||||||
{
|
|
||||||
#if UNITY_WEBGL && WEIXINMINIGAME && !UNITY_EDITOR
|
|
||||||
var createParameters = new WebPlayModeParameters();
|
|
||||||
string defaultHostServer = GetHostServerURL();
|
|
||||||
string fallbackHostServer = GetHostServerURL();
|
|
||||||
string packageRoot = $"{WeChatWASM.WX.env.USER_DATA_PATH}/__GAME_FILE_CACHE"; //注意:如果有子目录,请修改此处!
|
|
||||||
IRemoteServices remoteServices = new RemoteServices(defaultHostServer, fallbackHostServer);
|
|
||||||
createParameters.WebServerFileSystemParameters = WechatFileSystemCreater.CreateFileSystemParameters(packageRoot, remoteServices);
|
|
||||||
return package.InitializeAsync(createParameters);
|
|
||||||
#else
|
|
||||||
var createParameters = new WebPlayModeParameters();
|
|
||||||
createParameters.WebServerFileSystemParameters = FileSystemParameters.CreateDefaultWebServerFileSystemParameters();
|
|
||||||
return package.InitializeAsync(createParameters);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
private string GetHostServerURL()
|
|
||||||
{
|
|
||||||
string hostServerIP = $"https://home.gtuantuan.online:9444/{Application.productName}";
|
|
||||||
string appVersion = "v1";
|
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
|
||||||
if (UnityEditor.EditorUserBuildSettings.activeBuildTarget == UnityEditor.BuildTarget.Android)
|
|
||||||
// return $"{hostServerIP}/CDN/Android/{packageName}/{appVersion}";
|
|
||||||
return $"{hostServerIP}/CDN/PC/{data.packageName}/{appVersion}";
|
|
||||||
else if (UnityEditor.EditorUserBuildSettings.activeBuildTarget == UnityEditor.BuildTarget.iOS)
|
|
||||||
return $"{hostServerIP}/CDN/IPhone/{data.packageName}/{appVersion}";
|
|
||||||
else if (UnityEditor.EditorUserBuildSettings.activeBuildTarget == UnityEditor.BuildTarget.WebGL)
|
|
||||||
return $"{hostServerIP}/CDN/WebGL/{data.packageName}/{appVersion}";
|
|
||||||
else
|
|
||||||
return $"{hostServerIP}/CDN/PC/{data.packageName}/{appVersion}";
|
|
||||||
#else
|
|
||||||
if (Application.platform == RuntimePlatform.Android)
|
|
||||||
return $"{hostServerIP}/CDN/Android/{data.packageName}/{appVersion}";
|
|
||||||
else if (Application.platform == RuntimePlatform.IPhonePlayer)
|
|
||||||
return $"{hostServerIP}/CDN/IPhone/{data.packageName}/{appVersion}";
|
|
||||||
else if (Application.platform == RuntimePlatform.WebGLPlayer)
|
|
||||||
return $"{hostServerIP}/CDN/WebGL/{data.packageName}/{appVersion}";
|
|
||||||
else
|
|
||||||
return $"{hostServerIP}/CDN/PC/{data.packageName}/{appVersion}";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
private class RemoteServices : IRemoteServices
|
|
||||||
{
|
|
||||||
private readonly string _defaultHostServer;
|
|
||||||
private readonly string _fallbackHostServer;
|
|
||||||
|
|
||||||
public RemoteServices(string defaultHostServer, string fallbackHostServer)
|
|
||||||
{
|
|
||||||
_defaultHostServer = defaultHostServer;
|
|
||||||
_fallbackHostServer = fallbackHostServer;
|
|
||||||
}
|
|
||||||
string IRemoteServices.GetRemoteMainURL(string fileName)
|
|
||||||
{
|
|
||||||
return $"{_defaultHostServer}/{fileName}";
|
|
||||||
}
|
|
||||||
string IRemoteServices.GetRemoteFallbackURL(string fileName)
|
|
||||||
{
|
|
||||||
return $"{_fallbackHostServer}/{fileName}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
#region 版本和资源清单相关
|
|
||||||
public async UniTask<bool> RequestPackageVersion(bool showBox = true)
|
|
||||||
{
|
|
||||||
var operation = package.RequestPackageVersionAsync(true, 5);
|
|
||||||
await operation.ToUniTask();
|
|
||||||
if (operation.Status != EOperationStatus.Succeed)
|
|
||||||
{
|
|
||||||
if (showBox)
|
|
||||||
{
|
|
||||||
if(await CheckUseLocalVersion(operation))
|
|
||||||
{
|
|
||||||
string cachedVersion = GetCachedPackageVersion();
|
|
||||||
if (!string.IsNullOrEmpty(cachedVersion))
|
|
||||||
{
|
|
||||||
packageVersion = cachedVersion;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
packageVersion = operation.PackageVersion;
|
|
||||||
PatchEvent.UpdateStatus($"获取版本成功{data.packageName}");
|
|
||||||
Debug.Log($"获取版本成功{data.packageName}:{packageVersion}");
|
|
||||||
}
|
|
||||||
return operation.Status == EOperationStatus.Succeed;
|
|
||||||
}
|
|
||||||
public async UniTask<bool> CheckUseLocalVersion(RequestPackageVersionOperation operation)
|
|
||||||
{
|
|
||||||
var completionSource = new UniTaskCompletionSource<bool>();
|
|
||||||
MessageBox.Show()
|
|
||||||
.SetTitle($"{data.packageName}请求版本")
|
|
||||||
.SetContent($"{operation.Error}")
|
|
||||||
.AddButton("继续", (box) =>
|
|
||||||
{
|
|
||||||
completionSource.TrySetResult(true);
|
|
||||||
})
|
|
||||||
.AddButton("退出", (box) =>
|
|
||||||
{
|
|
||||||
completionSource.TrySetResult(false);
|
|
||||||
Application.Quit();
|
|
||||||
});
|
|
||||||
bool shouldContinue = await completionSource.Task;
|
|
||||||
return shouldContinue;
|
|
||||||
}
|
|
||||||
public async Task<string> GetBuildinPackageVersion()
|
|
||||||
{
|
|
||||||
var operation = new GetBuildinPackageVersionOperation(data.packageName);
|
|
||||||
YooAssets.StartOperation(operation);
|
|
||||||
await operation;
|
|
||||||
if (operation.Status == EOperationStatus.Succeed)
|
|
||||||
{
|
|
||||||
return operation.PackageVersion;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public string GetCachedPackageVersion()
|
|
||||||
{
|
|
||||||
if (PlayerPrefs.HasKey(PkgVersionKey))
|
|
||||||
{
|
|
||||||
return PlayerPrefs.GetString(PkgVersionKey);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SaveVersionToCache()
|
|
||||||
{
|
|
||||||
PlayerPrefs.SetString(PkgVersionKey, packageVersion);
|
|
||||||
PlayerPrefs.Save();
|
|
||||||
PatchEvent.UpdateStatus($"更新完成{data.packageName}");
|
|
||||||
Debug.Log($"更新{data.packageName}完成,版本号{packageVersion}");
|
|
||||||
|
|
||||||
}
|
|
||||||
public async UniTask<bool> UpdatePackageManifest(bool showBox = true)
|
|
||||||
{
|
|
||||||
var operation = package.UpdatePackageManifestAsync(packageVersion,10);
|
|
||||||
await operation.ToUniTask();
|
|
||||||
if (operation.Status != EOperationStatus.Succeed)
|
|
||||||
{
|
|
||||||
if (showBox)
|
|
||||||
{
|
|
||||||
MessageBox.Show()
|
|
||||||
.SetTitle($"{data.packageName}更新清单")
|
|
||||||
.SetContent($"{operation.Error}")
|
|
||||||
.AddButton("退出", (box) => { Application.Quit(); });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PatchEvent.UpdateStatus($"获取资源清单成功{data.packageName}");
|
|
||||||
Debug.Log($"获取资源清单成功{data.packageName}");
|
|
||||||
}
|
|
||||||
return operation.Status == EOperationStatus.Succeed;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
#region 下载相关
|
|
||||||
public bool CreateDownloader()
|
|
||||||
{
|
|
||||||
downloader = package.CreateResourceDownloader(data.downloadingMaxNum, data.failedTryAgain);
|
|
||||||
downloader.DownloadErrorCallback = data.downloadError;
|
|
||||||
downloader.DownloadFinishCallback = data.downloadFinish;
|
|
||||||
downloader.DownloadUpdateCallback = data.downloadUpdate;
|
|
||||||
if (downloader.TotalDownloadCount == 0) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
public async UniTask<bool> CheckDownloadOrSkip()
|
|
||||||
{
|
|
||||||
var completionSource = new UniTaskCompletionSource<bool>();
|
|
||||||
MessageBox.Show()
|
|
||||||
.SetTitle($"{data.packageName}发现更新")
|
|
||||||
.SetContent($"发现资源更新\n{GetCachedPackageVersion()}=>{packageVersion}: {FormatFileSize(downloader.TotalDownloadBytes)}")
|
|
||||||
.AddButton("下载", async (box) =>
|
|
||||||
{
|
|
||||||
bool success = await DownloadPackageFiles();
|
|
||||||
completionSource.TrySetResult(success);
|
|
||||||
})
|
|
||||||
.AddButton("跳过", async (box) =>
|
|
||||||
{
|
|
||||||
downloader.CancelDownload();
|
|
||||||
packageVersion = GetCachedPackageVersion();
|
|
||||||
await UpdatePackageManifest();
|
|
||||||
completionSource.TrySetResult(true);
|
|
||||||
})
|
|
||||||
.AddButton("退出", (box) =>
|
|
||||||
{
|
|
||||||
downloader.CancelDownload();
|
|
||||||
completionSource.TrySetResult(false);
|
|
||||||
#if UNITY_EDITOR
|
|
||||||
UnityEditor.EditorApplication.isPlaying = false;
|
|
||||||
#else
|
|
||||||
Application.Quit();
|
|
||||||
#endif
|
|
||||||
});
|
|
||||||
bool shouldContinue = await completionSource.Task;
|
|
||||||
return shouldContinue;
|
|
||||||
}
|
|
||||||
public async UniTask<bool> DownloadPackageFiles(bool showBox = true)
|
|
||||||
{
|
|
||||||
if (downloader.TotalDownloadCount == 0)
|
|
||||||
return true;
|
|
||||||
Debug.Log($"{data.packageName} DownloadPackageFiles {downloader.TotalDownloadCount}");
|
|
||||||
downloader.BeginDownload();
|
|
||||||
await downloader.ToUniTask();
|
|
||||||
if (downloader.Status != EOperationStatus.Succeed)
|
|
||||||
{
|
|
||||||
if (showBox)
|
|
||||||
{
|
|
||||||
MessageBox.Show()
|
|
||||||
.SetTitle($"{data.packageName}下载文件")
|
|
||||||
.SetContent($"{downloader.Error}")
|
|
||||||
.AddButton("退出", (box) => { Application.Quit(); });
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return downloader.Status == EOperationStatus.Succeed;
|
|
||||||
}
|
|
||||||
public async UniTask<bool> ClearCacheBundle(bool showBox = true)
|
|
||||||
{
|
|
||||||
var operation = package.ClearCacheFilesAsync(EFileClearMode.ClearUnusedBundleFiles);
|
|
||||||
await operation.ToUniTask();
|
|
||||||
if (operation.Status != EOperationStatus.Succeed)
|
|
||||||
{
|
|
||||||
if (showBox)
|
|
||||||
{
|
|
||||||
MessageBox.Show()
|
|
||||||
.SetTitle($"{data.packageName}清除缓存")
|
|
||||||
.SetContent($"{operation.Error}")
|
|
||||||
.AddButton("退出", (box) => { Application.Quit(); });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return operation.Status == EOperationStatus.Succeed;
|
|
||||||
}
|
|
||||||
public string FormatFileSize(long size)
|
|
||||||
{
|
|
||||||
if (size < 1024 * 1024)
|
|
||||||
return $"{(size / 1024f):F1}KB";
|
|
||||||
else
|
|
||||||
return $"{size / 1024f / 1024f:F1}MB";
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
using Cysharp.Threading.Tasks;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using UnityEngine;
|
|
||||||
using YooAsset;
|
|
||||||
|
|
||||||
public class PreloadOperation
|
|
||||||
{
|
|
||||||
PatchOperationData data;
|
|
||||||
PatchOperation operation;
|
|
||||||
public PreloadOperation(EPlayMode playMode)
|
|
||||||
{
|
|
||||||
data = new PatchOperationData();
|
|
||||||
data.packageName = "Preload";
|
|
||||||
data.playMode = playMode;
|
|
||||||
data.useBuildinFileSystem = true;
|
|
||||||
data.downloadingMaxNum = 10;
|
|
||||||
data.failedTryAgain = 3;
|
|
||||||
|
|
||||||
operation = new PatchOperation(data);
|
|
||||||
}
|
|
||||||
public async UniTask Execute()
|
|
||||||
{
|
|
||||||
#if !UNITY_EDITOR
|
|
||||||
CheckIsOffline();
|
|
||||||
#endif
|
|
||||||
if (!await operation.InitializePackage()) return;
|
|
||||||
var version = await GetBestPackageVersion();
|
|
||||||
#if UNITY_EDITOR
|
|
||||||
if (!await operation.RequestPackageVersion()) return;
|
|
||||||
version = operation.packageVersion;
|
|
||||||
#endif
|
|
||||||
//获取版本失败
|
|
||||||
if (version == null)
|
|
||||||
{
|
|
||||||
MessageBox.Show()
|
|
||||||
.SetTitle($"{operation.data.packageName}获取版本")
|
|
||||||
.SetContent("获取版本失败")
|
|
||||||
.AddButton("退出", (box) => { Application.Quit(); });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
operation.packageVersion = version;
|
|
||||||
if (!await operation.UpdatePackageManifest()) return;
|
|
||||||
await HotDllLoader.Inst.LoadDll(YooAssets.GetPackage("Preload"), "GameScripts.Preload");
|
|
||||||
await LoadAndShowPatchWindow();
|
|
||||||
MainUICanvas.Inst.InitBg.SetActive(false);
|
|
||||||
_ = UpdatePreloadPackage();
|
|
||||||
}
|
|
||||||
void CheckIsOffline()
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(operation.GetCachedPackageVersion()))
|
|
||||||
{
|
|
||||||
operation.data.playMode = EPlayMode.OfflinePlayMode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
async Task<string> GetBestPackageVersion()
|
|
||||||
{
|
|
||||||
string cachedVersion = operation.GetCachedPackageVersion();
|
|
||||||
if (!string.IsNullOrEmpty(cachedVersion))
|
|
||||||
{
|
|
||||||
return cachedVersion;
|
|
||||||
}
|
|
||||||
string buildinVersion = await operation.GetBuildinPackageVersion();
|
|
||||||
if (!string.IsNullOrEmpty(buildinVersion))
|
|
||||||
{
|
|
||||||
return buildinVersion;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
private async UniTask LoadAndShowPatchWindow()
|
|
||||||
{
|
|
||||||
var assetHandle = operation.package.LoadAssetAsync<GameObject>("PatchWindow");
|
|
||||||
await assetHandle.ToUniTask();
|
|
||||||
if (assetHandle.Status == EOperationStatus.Succeed)
|
|
||||||
GameObject.Instantiate(assetHandle.AssetObject, MainUICanvas.Inst.Medium);
|
|
||||||
Debug.Log("创建热更信息界面");
|
|
||||||
}
|
|
||||||
private async UniTask UpdatePreloadPackage()
|
|
||||||
{
|
|
||||||
if (!await operation.RequestPackageVersion(false)) return;
|
|
||||||
if (!await operation.UpdatePackageManifest(false)) return;
|
|
||||||
if (operation.CreateDownloader())
|
|
||||||
{
|
|
||||||
if (!await operation.DownloadPackageFiles()) return;
|
|
||||||
}
|
|
||||||
if (!await operation.ClearCacheBundle()) return;
|
|
||||||
operation.SaveVersionToCache();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Tuan.GameFramework
|
||||||
|
{
|
||||||
public class Singleton<T> where T : class, new()
|
public class Singleton<T> where T : class, new()
|
||||||
{
|
{
|
||||||
static T _inst;
|
static T _inst;
|
||||||
@@ -20,3 +22,4 @@ public class Singleton<T> where T:class,new()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Tuan.GameFramework
|
||||||
|
{
|
||||||
public class SingletonMono<T> : MonoBehaviour where T : MonoBehaviour
|
public class SingletonMono<T> : MonoBehaviour where T : MonoBehaviour
|
||||||
{
|
{
|
||||||
private static T _instance;
|
private static T _instance;
|
||||||
@@ -27,3 +29,4 @@ public class SingletonMono<T> : MonoBehaviour where T : MonoBehaviour
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 361581cda23892243b32bc232eada060
|
guid: b97f97e936caa3243b69996ed03e9a7b
|
||||||
folderAsset: yes
|
folderAsset: yes
|
||||||
DefaultImporter:
|
DefaultImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
79
Assets/GameRes/Main/InputActions/PlayerActions.inputactions
Normal file
79
Assets/GameRes/Main/InputActions/PlayerActions.inputactions
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"name": "PlayerActions",
|
||||||
|
"maps": [
|
||||||
|
{
|
||||||
|
"name": "Player",
|
||||||
|
"id": "8838403e-77e7-4938-931c-e7b6dd8da490",
|
||||||
|
"actions": [
|
||||||
|
{
|
||||||
|
"name": "Move",
|
||||||
|
"type": "Value",
|
||||||
|
"id": "16e058d1-98bd-4788-8905-cbbfe02198e1",
|
||||||
|
"expectedControlType": "Vector2",
|
||||||
|
"processors": "",
|
||||||
|
"interactions": "",
|
||||||
|
"initialStateCheck": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bindings": [
|
||||||
|
{
|
||||||
|
"name": "WASD",
|
||||||
|
"id": "969f48c2-0733-4928-b753-b138a70296af",
|
||||||
|
"path": "2DVector",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "",
|
||||||
|
"action": "Move",
|
||||||
|
"isComposite": true,
|
||||||
|
"isPartOfComposite": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "up",
|
||||||
|
"id": "72c4179b-427a-4077-9aa4-5b13b797cc0b",
|
||||||
|
"path": "<Keyboard>/w",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "",
|
||||||
|
"action": "Move",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "down",
|
||||||
|
"id": "9a0c2556-7cde-48d5-b5e0-f02b4c3198d2",
|
||||||
|
"path": "<Keyboard>/s",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "",
|
||||||
|
"action": "Move",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "left",
|
||||||
|
"id": "5e78290e-53bd-43f3-98fd-86caef589cdf",
|
||||||
|
"path": "<Keyboard>/a",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "",
|
||||||
|
"action": "Move",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "right",
|
||||||
|
"id": "8770c0d9-f0a5-4e93-b4e0-e30272211973",
|
||||||
|
"path": "<Keyboard>/d",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "",
|
||||||
|
"action": "Move",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"controlSchemes": []
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1af8d28e241e7634b985b9ffe793d1bf
|
||||||
|
ScriptedImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
script: {fileID: 11500000, guid: 8404be70184654265930450def6a9037, type: 3}
|
||||||
|
generateWrapperCode: 0
|
||||||
|
wrapperCodePath:
|
||||||
|
wrapperClassName:
|
||||||
|
wrapperCodeNamespace:
|
||||||
@@ -8,7 +8,8 @@
|
|||||||
"GUID:6055be8ebefd69e48b49212b09b47b2f",
|
"GUID:6055be8ebefd69e48b49212b09b47b2f",
|
||||||
"GUID:f51ebe6a0ceec4240a699833d6309b23",
|
"GUID:f51ebe6a0ceec4240a699833d6309b23",
|
||||||
"GUID:e34a5702dd353724aa315fb8011f08c3",
|
"GUID:e34a5702dd353724aa315fb8011f08c3",
|
||||||
"GUID:75469ad4d38634e559750d17036d5f7c"
|
"GUID:75469ad4d38634e559750d17036d5f7c",
|
||||||
|
"GUID:928f8a513cd12e84cb0d3c0a21a84e2f"
|
||||||
],
|
],
|
||||||
"includePlatforms": [],
|
"includePlatforms": [],
|
||||||
"excludePlatforms": [],
|
"excludePlatforms": [],
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
using Cysharp.Threading.Tasks;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net.NetworkInformation;
|
|
||||||
using System.Threading;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Networking;
|
using Cysharp.Threading.Tasks;
|
||||||
using YooAsset;
|
using Tuan.GameFramework;
|
||||||
|
using Tuan.GameScripts.Preload;
|
||||||
|
|
||||||
|
namespace Tuan.GameScripts.Main
|
||||||
|
{
|
||||||
public class GameStart : MonoBehaviour
|
public class GameStart : MonoBehaviour
|
||||||
{
|
{
|
||||||
// Start is called once before the first execution of Update after the MonoBehaviour is created
|
// Start is called once before the first execution of Update after the MonoBehaviour is created
|
||||||
@@ -15,7 +12,7 @@ public class GameStart : MonoBehaviour
|
|||||||
{
|
{
|
||||||
Debug.Log("GameStart");
|
Debug.Log("GameStart");
|
||||||
GamePreload.Inst.Test("call by GameStart");
|
GamePreload.Inst.Test("call by GameStart");
|
||||||
_=FrameSplittingTest(1);
|
// _ = FrameSplittingTest(1);
|
||||||
await UIManager.Inst.ShowUIAsync<SimpleR3Test>("test1", MainUICanvas.Inst.Medium);
|
await UIManager.Inst.ShowUIAsync<SimpleR3Test>("test1", MainUICanvas.Inst.Medium);
|
||||||
}
|
}
|
||||||
async UniTask FrameSplittingTest(int delayFrame)
|
async UniTask FrameSplittingTest(int delayFrame)
|
||||||
@@ -27,3 +24,4 @@ public class GameStart : MonoBehaviour
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,11 @@
|
|||||||
using static UnityEngine.InputSystem.InputAction;
|
using static UnityEngine.InputSystem.InputAction;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using R3;
|
using UnityEngine.InputSystem;
|
||||||
|
using YooAsset;
|
||||||
|
using Cysharp.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Tuan.GameScripts.Main
|
||||||
|
{
|
||||||
public class ThirdCharacterController : MonoBehaviour
|
public class ThirdCharacterController : MonoBehaviour
|
||||||
{
|
{
|
||||||
public CharacterController characterController;
|
public CharacterController characterController;
|
||||||
@@ -17,10 +21,23 @@ public class ThirdCharacterController : MonoBehaviour
|
|||||||
public float maxCameraDistance = 10f;
|
public float maxCameraDistance = 10f;
|
||||||
public float cameraZoomSpeed = 0.1f;
|
public float cameraZoomSpeed = 0.1f;
|
||||||
|
|
||||||
|
InputActionAsset playerActions;
|
||||||
Vector2 moveInput;
|
Vector2 moveInput;
|
||||||
|
|
||||||
|
async void Awake()
|
||||||
|
{
|
||||||
|
await LoadInputActonAsset();
|
||||||
|
}
|
||||||
|
async UniTask LoadInputActonAsset()
|
||||||
|
{
|
||||||
|
AssetHandle handle = YooAssets.LoadAssetAsync<InputActionAsset>("PlayerActions");
|
||||||
|
await handle.ToUniTask();
|
||||||
|
playerActions = handle.AssetObject as InputActionAsset;
|
||||||
|
}
|
||||||
|
|
||||||
public void OnMove(CallbackContext context)
|
public void OnMove(CallbackContext context)
|
||||||
{
|
{
|
||||||
moveInput = context.ReadValue<Vector2>();
|
moveInput = context.ReadValue<Vector2>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
using R3;
|
using R3;
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
namespace Tuan.GameScripts.Main
|
||||||
|
{
|
||||||
public class SimpleR3Test : UIBase
|
public class SimpleR3Test : UIBase
|
||||||
{
|
{
|
||||||
public SerializableReactiveProperty<float> value = new(0);
|
public SerializableReactiveProperty<float> value = new(0);
|
||||||
@@ -15,3 +16,4 @@ public class SimpleR3Test : UIBase
|
|||||||
value.BindToInputField(inputField).AddTo(this);
|
value.BindToInputField(inputField).AddTo(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Tuan.GameScripts.Main
|
||||||
|
{
|
||||||
public class UIBase : MonoBehaviour
|
public class UIBase : MonoBehaviour
|
||||||
{
|
{
|
||||||
public RectTransform rectTransform
|
public RectTransform rectTransform
|
||||||
@@ -36,3 +38,4 @@ public class UIBase : MonoBehaviour
|
|||||||
SetFull();
|
SetFull();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
using Cysharp.Threading.Tasks;
|
using Cysharp.Threading.Tasks;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using Tuan.GameFramework;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using YooAsset;
|
using YooAsset;
|
||||||
|
|
||||||
|
namespace Tuan.GameScripts.Main
|
||||||
|
{
|
||||||
public class UIManager : Singleton<UIManager>
|
public class UIManager : Singleton<UIManager>
|
||||||
{
|
{
|
||||||
Dictionary<string, UIBase> openedUIs = new Dictionary<string, UIBase>();
|
Dictionary<string, UIBase> openedUIs = new Dictionary<string, UIBase>();
|
||||||
@@ -154,3 +157,4 @@ public class UIManager : Singleton<UIManager>
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@ using TMPro;
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
|
|
||||||
namespace R3
|
namespace Tuan.GameScripts.Main
|
||||||
{
|
{
|
||||||
public static class UnityUIBindings
|
public static class UnityUIBindings
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using Tuan.GameFramework;
|
||||||
|
|
||||||
|
namespace Tuan.GameScripts.Preload
|
||||||
|
{
|
||||||
public class GamePreload : Singleton<GamePreload>
|
public class GamePreload : Singleton<GamePreload>
|
||||||
{
|
{
|
||||||
public void Test(string msg)
|
public void Test(string msg)
|
||||||
@@ -7,3 +10,4 @@ public class GamePreload : Singleton<GamePreload>
|
|||||||
Debug.Log($"GamePreload.Test:{msg}");
|
Debug.Log($"GamePreload.Test:{msg}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
using UnityEngine.Video;
|
using UnityEngine.Video;
|
||||||
|
using Tuan.GameFramework;
|
||||||
|
|
||||||
|
namespace Tuan.GameScripts.Preload
|
||||||
|
{
|
||||||
public class PatchWindow : MonoBehaviour
|
public class PatchWindow : MonoBehaviour
|
||||||
{
|
{
|
||||||
public Text statusText;
|
public Text statusText;
|
||||||
@@ -45,3 +48,4 @@ public class PatchWindow : MonoBehaviour
|
|||||||
gameObject.SetActive(false);
|
gameObject.SetActive(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@@ -19,5 +19,8 @@
|
|||||||
<Group GroupActiveRule="EnableGroup" GroupName="UI" GroupDesc="" AssetTags="">
|
<Group GroupActiveRule="EnableGroup" GroupName="UI" GroupDesc="" AssetTags="">
|
||||||
<Collector CollectPath="Assets/GameRes/Main/UI" CollectGUID="92ee981811aa81945b9aefad990f18ec" CollectType="MainAssetCollector" AddressRule="AddressByFileName" PackRule="PackDirectory" FilterRule="CollectAll" UserData="" AssetTags="" />
|
<Collector CollectPath="Assets/GameRes/Main/UI" CollectGUID="92ee981811aa81945b9aefad990f18ec" CollectType="MainAssetCollector" AddressRule="AddressByFileName" PackRule="PackDirectory" FilterRule="CollectAll" UserData="" AssetTags="" />
|
||||||
</Group>
|
</Group>
|
||||||
|
<Group GroupActiveRule="EnableGroup" GroupName="InputActions" GroupDesc="" AssetTags="">
|
||||||
|
<Collector CollectPath="Assets/GameRes/Main/InputActions" CollectGUID="b97f97e936caa3243b69996ed03e9a7b" CollectType="MainAssetCollector" AddressRule="AddressByFileName" PackRule="PackSeparately" FilterRule="CollectAll" UserData="" AssetTags="" />
|
||||||
|
</Group>
|
||||||
</Package>
|
</Package>
|
||||||
</root>
|
</root>
|
||||||
@@ -99,3 +99,16 @@ MonoBehaviour:
|
|||||||
FilterRuleName: CollectAll
|
FilterRuleName: CollectAll
|
||||||
AssetTags:
|
AssetTags:
|
||||||
UserData:
|
UserData:
|
||||||
|
- GroupName: InputActions
|
||||||
|
GroupDesc:
|
||||||
|
AssetTags:
|
||||||
|
ActiveRuleName: EnableGroup
|
||||||
|
Collectors:
|
||||||
|
- CollectPath: Assets/GameRes/Main/InputActions
|
||||||
|
CollectorGUID: b97f97e936caa3243b69996ed03e9a7b
|
||||||
|
CollectorType: 0
|
||||||
|
AddressRuleName: AddressByFileName
|
||||||
|
PackRuleName: PackSeparately
|
||||||
|
FilterRuleName: CollectAll
|
||||||
|
AssetTags:
|
||||||
|
UserData:
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"version": 1,
|
||||||
"name": "InputSystem_Actions",
|
"name": "InputSystem_Actions",
|
||||||
"maps": [
|
"maps": [
|
||||||
{
|
{
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 8a55ef7d1bba14cc982b478d482c4461
|
guid: 9f1a339e4d0a6b444a9e489b81103fe3
|
||||||
folderAsset: yes
|
folderAsset: yes
|
||||||
DefaultImporter:
|
DefaultImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 2cceff5ec1f84bd0a6a9b4ed7719527c
|
guid: 4118f9f3fcb736649a2ca8beab5d745c
|
||||||
timeCreated: 1651978895
|
timeCreated: 1651978895
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: e1c9a3a6de2246bf88547a6b59b99b9f
|
guid: 6c792e3f64e1fe144b0e2d0909295415
|
||||||
timeCreated: 1650851321
|
timeCreated: 1650851321
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 1278a46ce459c5a46b4eaeda148684ef
|
guid: 928f8a513cd12e84cb0d3c0a21a84e2f
|
||||||
AssemblyDefinitionImporter:
|
AssemblyDefinitionImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
userData:
|
userData:
|
||||||
@@ -4,3 +4,4 @@
|
|||||||
[assembly: InternalsVisibleTo("UniTask.Addressables")]
|
[assembly: InternalsVisibleTo("UniTask.Addressables")]
|
||||||
[assembly: InternalsVisibleTo("UniTask.DOTween")]
|
[assembly: InternalsVisibleTo("UniTask.DOTween")]
|
||||||
[assembly: InternalsVisibleTo("UniTask.TextMeshPro")]
|
[assembly: InternalsVisibleTo("UniTask.TextMeshPro")]
|
||||||
|
[assembly: InternalsVisibleTo("UniTask.YooAsset")]
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 47 KiB |
@@ -1,153 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: d90b9b066363f08419ff51004479d5b7
|
|
||||||
TextureImporter:
|
|
||||||
internalIDToNameTable: []
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 13
|
|
||||||
mipmaps:
|
|
||||||
mipMapMode: 0
|
|
||||||
enableMipMap: 1
|
|
||||||
sRGBTexture: 1
|
|
||||||
linearTexture: 0
|
|
||||||
fadeOut: 0
|
|
||||||
borderMipMap: 0
|
|
||||||
mipMapsPreserveCoverage: 0
|
|
||||||
alphaTestReferenceValue: 0.5
|
|
||||||
mipMapFadeDistanceStart: 1
|
|
||||||
mipMapFadeDistanceEnd: 3
|
|
||||||
bumpmap:
|
|
||||||
convertToNormalMap: 0
|
|
||||||
externalNormalMap: 0
|
|
||||||
heightScale: 0.25
|
|
||||||
normalMapFilter: 0
|
|
||||||
flipGreenChannel: 0
|
|
||||||
isReadable: 0
|
|
||||||
streamingMipmaps: 0
|
|
||||||
streamingMipmapsPriority: 0
|
|
||||||
vTOnly: 0
|
|
||||||
ignoreMipmapLimit: 0
|
|
||||||
grayScaleToAlpha: 0
|
|
||||||
generateCubemap: 6
|
|
||||||
cubemapConvolution: 0
|
|
||||||
seamlessCubemap: 0
|
|
||||||
textureFormat: 1
|
|
||||||
maxTextureSize: 2048
|
|
||||||
textureSettings:
|
|
||||||
serializedVersion: 2
|
|
||||||
filterMode: 1
|
|
||||||
aniso: 1
|
|
||||||
mipBias: 0
|
|
||||||
wrapU: 0
|
|
||||||
wrapV: 0
|
|
||||||
wrapW: 0
|
|
||||||
nPOTScale: 1
|
|
||||||
lightmap: 0
|
|
||||||
compressionQuality: 50
|
|
||||||
spriteMode: 0
|
|
||||||
spriteExtrude: 1
|
|
||||||
spriteMeshType: 1
|
|
||||||
alignment: 0
|
|
||||||
spritePivot: {x: 0.5, y: 0.5}
|
|
||||||
spritePixelsToUnits: 100
|
|
||||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
|
||||||
spriteGenerateFallbackPhysicsShape: 1
|
|
||||||
alphaUsage: 1
|
|
||||||
alphaIsTransparency: 0
|
|
||||||
spriteTessellationDetail: -1
|
|
||||||
textureType: 0
|
|
||||||
textureShape: 1
|
|
||||||
singleChannelComponent: 0
|
|
||||||
flipbookRows: 1
|
|
||||||
flipbookColumns: 1
|
|
||||||
maxTextureSizeSet: 0
|
|
||||||
compressionQualitySet: 0
|
|
||||||
textureFormatSet: 0
|
|
||||||
ignorePngGamma: 0
|
|
||||||
applyGammaDecoding: 0
|
|
||||||
swizzle: 50462976
|
|
||||||
cookieLightType: 0
|
|
||||||
platformSettings:
|
|
||||||
- serializedVersion: 3
|
|
||||||
buildTarget: DefaultTexturePlatform
|
|
||||||
maxTextureSize: 2048
|
|
||||||
resizeAlgorithm: 0
|
|
||||||
textureFormat: -1
|
|
||||||
textureCompression: 1
|
|
||||||
compressionQuality: 50
|
|
||||||
crunchedCompression: 0
|
|
||||||
allowsAlphaSplitting: 0
|
|
||||||
overridden: 0
|
|
||||||
ignorePlatformSupport: 0
|
|
||||||
androidETC2FallbackOverride: 0
|
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
|
||||||
- serializedVersion: 3
|
|
||||||
buildTarget: Standalone
|
|
||||||
maxTextureSize: 2048
|
|
||||||
resizeAlgorithm: 0
|
|
||||||
textureFormat: -1
|
|
||||||
textureCompression: 1
|
|
||||||
compressionQuality: 50
|
|
||||||
crunchedCompression: 0
|
|
||||||
allowsAlphaSplitting: 0
|
|
||||||
overridden: 0
|
|
||||||
ignorePlatformSupport: 0
|
|
||||||
androidETC2FallbackOverride: 0
|
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
|
||||||
- serializedVersion: 3
|
|
||||||
buildTarget: iPhone
|
|
||||||
maxTextureSize: 2048
|
|
||||||
resizeAlgorithm: 0
|
|
||||||
textureFormat: -1
|
|
||||||
textureCompression: 1
|
|
||||||
compressionQuality: 50
|
|
||||||
crunchedCompression: 0
|
|
||||||
allowsAlphaSplitting: 0
|
|
||||||
overridden: 0
|
|
||||||
ignorePlatformSupport: 0
|
|
||||||
androidETC2FallbackOverride: 0
|
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
|
||||||
- serializedVersion: 3
|
|
||||||
buildTarget: WebGL
|
|
||||||
maxTextureSize: 2048
|
|
||||||
resizeAlgorithm: 0
|
|
||||||
textureFormat: -1
|
|
||||||
textureCompression: 1
|
|
||||||
compressionQuality: 50
|
|
||||||
crunchedCompression: 0
|
|
||||||
allowsAlphaSplitting: 0
|
|
||||||
overridden: 0
|
|
||||||
ignorePlatformSupport: 0
|
|
||||||
androidETC2FallbackOverride: 0
|
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
|
||||||
- serializedVersion: 3
|
|
||||||
buildTarget: Android
|
|
||||||
maxTextureSize: 2048
|
|
||||||
resizeAlgorithm: 0
|
|
||||||
textureFormat: -1
|
|
||||||
textureCompression: 1
|
|
||||||
compressionQuality: 50
|
|
||||||
crunchedCompression: 0
|
|
||||||
allowsAlphaSplitting: 0
|
|
||||||
overridden: 0
|
|
||||||
ignorePlatformSupport: 0
|
|
||||||
androidETC2FallbackOverride: 0
|
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
|
||||||
spriteSheet:
|
|
||||||
serializedVersion: 2
|
|
||||||
sprites: []
|
|
||||||
outline: []
|
|
||||||
physicsShape: []
|
|
||||||
bones: []
|
|
||||||
spriteID:
|
|
||||||
internalID: 0
|
|
||||||
vertices: []
|
|
||||||
indices:
|
|
||||||
edges: []
|
|
||||||
weights: []
|
|
||||||
secondaryTextures: []
|
|
||||||
nameFileIdTable: {}
|
|
||||||
mipmapLimitGroupName:
|
|
||||||
pSDRemoveMatte: 0
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
# UniTask 扩展
|
|
||||||
|
|
||||||
### 代码示例
|
|
||||||
|
|
||||||
```csharp
|
|
||||||
using System;
|
|
||||||
using UnityEngine;
|
|
||||||
using YooAsset;
|
|
||||||
using Cysharp.Threading.Tasks;
|
|
||||||
|
|
||||||
public class TestTask : MonoBehaviour
|
|
||||||
{
|
|
||||||
private async void Start()
|
|
||||||
{
|
|
||||||
var assetHandle = YooAssets.LoadAssetAsync<GameObject>("UIHome");
|
|
||||||
await assetHandle.ToUniTask();
|
|
||||||
Debug.Log($"{assetHandle.Status}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 使用教程A
|
|
||||||
|
|
||||||
1. 下载 [UniTask](https://github.com/Cysharp/UniTask) 源码并导入到工程内。
|
|
||||||
|
|
||||||
2. 修改UniTask源码
|
|
||||||
|
|
||||||
UniTask/Runtime/_InternalVisibleTo.cs
|
|
||||||
|
|
||||||
```csharp
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
|
|
||||||
[assembly: InternalsVisibleTo("UniTask.Linq")]
|
|
||||||
[assembly: InternalsVisibleTo("UniTask.Addressables")]
|
|
||||||
[assembly: InternalsVisibleTo("UniTask.DOTween")]
|
|
||||||
[assembly: InternalsVisibleTo("UniTask.TextMeshPro")]
|
|
||||||
[assembly: InternalsVisibleTo("UniTask.YooAsset")] //增加此行代码
|
|
||||||
```
|
|
||||||
|
|
||||||
3. 拷贝YOO提供的扩展脚本到工程内。
|
|
||||||
|
|
||||||
YooAssets/Samples/UniTask Sample/UniTask目录
|
|
||||||
|
|
||||||
4. 添加引擎里的宏定义(在宏定义未生效的情况下)
|
|
||||||
|
|
||||||
Project Settings --> Player --> Scripting Define Symbols
|
|
||||||
|
|
||||||
```
|
|
||||||
UNITASK_YOOASSET_SUPPORT
|
|
||||||
```
|
|
||||||
|
|
||||||
5. 重启Unity引擎
|
|
||||||
|
|
||||||
重新打开工程后用上面的代码示例验证,看下是否有编译错误!
|
|
||||||
|
|
||||||
### 使用教程B
|
|
||||||
|
|
||||||
1. 通过Package导入UniTask插件
|
|
||||||
|
|
||||||
2. 拷贝YOO提供的扩展脚本到工程内。
|
|
||||||
|
|
||||||
YooAssets/Samples/UniTask Sample/UniTask目录
|
|
||||||
|
|
||||||
YooAssets/Samples/UniTask Sample/UniTaskRef目录
|
|
||||||
|
|
||||||
3. 添加引擎里的宏定义(在宏定义未生效的情况下)
|
|
||||||
|
|
||||||
Project Settings --> Player --> Scripting Define Symbols
|
|
||||||
|
|
||||||
```
|
|
||||||
UNITASK_YOOASSET_SUPPORT
|
|
||||||
```
|
|
||||||
|
|
||||||
4. 重启Unity引擎
|
|
||||||
|
|
||||||
重新打开工程后用上面的代码示例验证,看下是否有编译错误!
|
|
||||||
|
|
||||||
### 注意事项
|
|
||||||
|
|
||||||
- 注意检测程序集引用是否丢失
|
|
||||||
|
|
||||||

|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 6375cc739b170490fbc6c38181b2c600
|
|
||||||
TextScriptImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: aaf714c0c57134e7ab7675a7528c1505
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 2bbb725df946a6f49afbc3ef104fbd8f
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: a06b0036f802a1c48805344cdbdfff1f
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: f4f000ae8d64e444fa5bf1090b648f76
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"reference": "GUID:f51ebe6a0ceec4240a699833d6309b23"
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: fb1a9972a41e10f40a752774a402830a
|
|
||||||
AssemblyDefinitionReferenceImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
using System.Runtime.CompilerServices;
|
|
||||||
|
|
||||||
[assembly: InternalsVisibleTo("UniTask.YooAsset")]
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: dc0f48d84ee89ad499856840eea08a64
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
Reference in New Issue
Block a user