Compare commits

...

8 Commits

Author SHA1 Message Date
何冠峰
06a50a049e add mini game sample 2025-06-13 18:31:05 +08:00
何冠峰
6f049e2427 add mini game sample
小游戏扩展库独立
2025-06-13 18:19:35 +08:00
何冠峰
01c08a46ab fix #564 2025-06-13 17:39:30 +08:00
何冠峰
31dc5b494d fix #569 2025-06-13 17:25:13 +08:00
何冠峰
18e74e906e fix #551 2025-06-13 17:18:38 +08:00
何冠峰
4f62b249b4 update TableView
增加AssetObjectCell类
2025-05-19 16:25:16 +08:00
何冠峰
fe7f9bff08 fix #552 2025-05-15 15:38:13 +08:00
何冠峰
e71077f294 fix space shooter quit game error
修复太空战机DEMO在退出运行模式时的报错。
2025-05-13 17:53:17 +08:00
76 changed files with 227 additions and 36 deletions

View File

@@ -196,6 +196,32 @@ namespace YooAsset.Editor
}
}
/// <summary>
/// 导入单个报告对象
/// </summary>
public void ImportSingleReprotFile(ScanReport report)
{
_reportCombiner = new ScanReportCombiner();
try
{
_reportCombiner.Combine(report);
// 刷新页面
RefreshToolbar();
FillTableView();
RebuildView();
}
catch (System.Exception e)
{
_reportCombiner = null;
_titleLabel.text = "导入报告失败!";
_descLabel.text = e.Message;
UnityEngine.Debug.LogError(e.StackTrace);
}
}
private void ImportSingleBtn_clicked()
{
string selectFilePath = EditorUtility.OpenFilePanel("导入报告", _lastestOpenFolder, "json");
@@ -445,16 +471,32 @@ namespace YooAsset.Editor
columnStyle.Units = header.Units;
var column = new TableColumn(header.HeaderTitle, header.HeaderTitle, columnStyle);
column.MakeCell = () =>
{
if (header.HeaderType == EHeaderType.AssetObject)
{
var objectFiled = new ObjectField();
return objectFiled;
}
else
{
var label = new Label();
label.style.marginLeft = 3f;
label.style.unityTextAlign = TextAnchor.MiddleLeft;
return label;
}
};
column.BindCell = (VisualElement element, ITableData data, ITableCell cell) =>
{
if (header.HeaderType == EHeaderType.AssetObject)
{
var objectFiled = element as ObjectField;
objectFiled.value = (UnityEngine.Object)cell.GetDisplayObject();
}
else
{
var infoLabel = element as Label;
infoLabel.text = (string)cell.GetDisplayObject();
}
};
_elementTableView.AddColumn(column);
}
@@ -480,6 +522,10 @@ namespace YooAsset.Editor
{
tableData.AddAssetPathCell(scanInfo.HeaderTitle, scanInfo.ScanInfo);
}
else if (header.HeaderType == EHeaderType.AssetObject)
{
tableData.AddAssetObjectCell(scanInfo.HeaderTitle, scanInfo.ScanInfo);
}
else if (header.HeaderType == EHeaderType.StringValue)
{
tableData.AddStringValueCell(scanInfo.HeaderTitle, scanInfo.ScanInfo);

View File

@@ -8,6 +8,11 @@ namespace YooAsset.Editor
/// </summary>
AssetPath,
/// <summary>
/// 资源对象
/// </summary>
AssetObject,
/// <summary>
/// 字符串
/// </summary>

View File

@@ -126,6 +126,12 @@ namespace YooAsset.Editor
if (string.IsNullOrEmpty(guid))
throw new Exception($"{HeaderTitle} value is invalid asset path : {value}");
}
else if (HeaderType == EHeaderType.AssetObject)
{
string guid = AssetDatabase.AssetPathToGUID(value);
if (string.IsNullOrEmpty(guid))
throw new Exception($"{HeaderTitle} value is invalid asset object : {value}");
}
else if (HeaderType == EHeaderType.DoubleValue)
{
if (double.TryParse(value, out double doubleValue) == false)

View File

@@ -46,7 +46,7 @@ namespace YooAsset.Editor
}
catch (Exception e)
{
return new ScannerResult(e.Message);
return new ScannerResult(e.StackTrace);
}
}

View File

@@ -52,7 +52,7 @@ namespace YooAsset.Editor
if (Succeed)
{
var reproterWindow = AssetArtReporterWindow.OpenWindow();
reproterWindow.ImportSingleReprotFile(ReprotFilePath);
reproterWindow.ImportSingleReprotFile(Report);
}
}
}

View File

@@ -70,7 +70,11 @@ namespace YooAsset.Editor
foreach (var cacheInfoPair in _database)
{
var assetPath = cacheInfoPair.Key;
#if UNITY_2021_3_OR_NEWER
var assetGUID = AssetDatabase.AssetPathToGUID(assetPath, AssetPathToGUIDOptions.OnlyExistingAssets);
#else
var assetGUID = AssetDatabase.AssetPathToGUID(assetPath);
#endif
if (string.IsNullOrEmpty(assetGUID))
{
removeList.Add(assetPath);

View File

@@ -0,0 +1,42 @@
#if UNITY_2019_4_OR_NEWER
using UnityEditor;
using System;
namespace YooAsset.Editor
{
public class AssetObjectCell : ITableCell, IComparable
{
public string SearchTag { private set; get; }
public object CellValue { set; get; }
public string StringValue
{
get
{
return (string)CellValue;
}
}
public AssetObjectCell(string searchTag, string assetPath)
{
SearchTag = searchTag;
CellValue = assetPath;
}
public object GetDisplayObject()
{
return AssetDatabase.LoadMainAssetAtPath(StringValue);
}
public int CompareTo(object other)
{
if (other is AssetObjectCell cell)
{
return this.StringValue.CompareTo(cell.StringValue);
}
else
{
return 0;
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 39db4a569a0f69443a7675e19c99c389
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -31,9 +31,14 @@ namespace YooAsset.Editor
var cell = new ButtonCell(searchTag);
Cells.Add(cell);
}
public void AddAssetPathCell(string searchTag, string path)
public void AddAssetPathCell(string searchTag, string assetPath)
{
var cell = new AssetPathCell(searchTag, path);
var cell = new AssetPathCell(searchTag, assetPath);
Cells.Add(cell);
}
public void AddAssetObjectCell(string searchTag, string assetPath)
{
var cell = new AssetObjectCell(searchTag, assetPath);
Cells.Add(cell);
}
public void AddStringValueCell(string searchTag, string value)

View File

@@ -5,6 +5,7 @@
[assembly: InternalsVisibleTo("YooAsset.Test.Editor")]
// 外部友元
[assembly: InternalsVisibleTo("YooAsset.MiniGame")]
[assembly: InternalsVisibleTo("YooAsset.RuntimeExtension")]
[assembly: InternalsVisibleTo("YooAsset.EditorExtension")]
[assembly: InternalsVisibleTo("Assembly-CSharp-Editor")]

View File

@@ -69,6 +69,8 @@ namespace YooAsset
url = new System.Uri(path).ToString();
#elif UNITY_STANDALONE || UNITY_WSA
url = StringUtility.Format("file:///{0}", path);
#elif UNITY_TVOS
url = StringUtility.Format("file:///{0}", path);
#else
throw new System.NotImplementedException();
#endif

View File

@@ -34,6 +34,20 @@ namespace YooAsset
return str.Remove(index); //"assets/config/test.unity3d" --> "assets/config/test"
}
/// <summary>
/// URL地址是否包含双斜杠
/// 注意:只检查协议之后的部分
/// </summary>
public static bool HasDoubleSlashes(string url)
{
if (url == null)
throw new ArgumentNullException();
int protocolIndex = url.IndexOf("://");
string partToCheck = protocolIndex == -1 ? url : url.Substring(protocolIndex + 3);
return partToCheck.Contains("//") || partToCheck.Contains(@"\\");
}
/// <summary>
/// 合并路径
/// </summary>

View File

@@ -75,7 +75,14 @@ namespace YooAsset
if (_driver != null)
GameObject.Destroy(_driver);
OnApplicationQuit(true);
// 终止并清空所有包裹的异步操作
ClearAllPackageOperation();
// 卸载所有AssetBundle
AssetBundle.UnloadAllAssetBundles(true);
// 清空资源包裹列表
_packages.Clear();
}
}
@@ -91,25 +98,15 @@ namespace YooAsset
}
/// <summary>
/// 应用程序退出处理
/// 终止并清空所有包裹的异步操作
/// </summary>
internal static void OnApplicationQuit(bool unloadAllAssetBundles)
internal static void ClearAllPackageOperation()
{
// 说明在编辑器下确保播放被停止时IO类操作被终止。
foreach (var package in _packages)
{
OperationSystem.ClearPackageOperation(package.PackageName);
}
OperationSystem.DestroyAll();
// 清空资源包裹列表
_packages.Clear();
// 卸载所有AssetBundle
if (unloadAllAssetBundles)
{
AssetBundle.UnloadAllAssetBundles(true);
}
}
/// <summary>

View File

@@ -24,7 +24,8 @@ namespace YooAsset
#if UNITY_EDITOR
void OnApplicationQuit()
{
YooAssets.OnApplicationQuit(false);
// 说明在编辑器下确保播放被停止时IO类操作被终止。
YooAssets.ClearAllPackageOperation();
}
#endif

View File

@@ -2,9 +2,7 @@
"name": "YooAsset.RuntimeExtension",
"rootNamespace": "",
"references": [
"GUID:e34a5702dd353724aa315fb8011f08c3",
"GUID:5efd170ecd8084500bed5692932fe14e",
"GUID:bb21d6197862c4c3e863390dec9859a7"
"GUID:e34a5702dd353724aa315fb8011f08c3"
],
"includePlatforms": [],
"excludePlatforms": [],

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 5280dfac6a481ee429c769ba5688c9d2
guid: 2bbcb90032364234abe49c81b95714e1
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b127fedb48547954b9c54084b6a32a65
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -11,14 +11,16 @@ internal class TTFSRequestPackageVersionOperation : FSRequestPackageVersionOpera
}
private readonly TiktokFileSystem _fileSystem;
private readonly bool _appendTimeTicks;
private readonly int _timeout;
private RequestTiktokPackageVersionOperation _requestPackageVersionOp;
private ESteps _steps = ESteps.None;
internal TTFSRequestPackageVersionOperation(TiktokFileSystem fileSystem, int timeout)
internal TTFSRequestPackageVersionOperation(TiktokFileSystem fileSystem, bool appendTimeTicks, int timeout)
{
_fileSystem = fileSystem;
_appendTimeTicks = appendTimeTicks;
_timeout = timeout;
}
internal override void InternalStart()
@@ -34,7 +36,7 @@ internal class TTFSRequestPackageVersionOperation : FSRequestPackageVersionOpera
{
if (_requestPackageVersionOp == null)
{
_requestPackageVersionOp = new RequestTiktokPackageVersionOperation(_fileSystem, _timeout);
_requestPackageVersionOp = new RequestTiktokPackageVersionOperation(_fileSystem, _appendTimeTicks, _timeout);
_requestPackageVersionOp.StartOperation();
AddChildOperation(_requestPackageVersionOp);
}

View File

@@ -11,6 +11,7 @@ internal class RequestTiktokPackageVersionOperation : AsyncOperationBase
}
private readonly TiktokFileSystem _fileSystem;
private readonly bool _appendTimeTicks;
private readonly int _timeout;
private UnityWebTextRequestOperation _webTextRequestOp;
private int _requestCount = 0;
@@ -22,9 +23,10 @@ internal class RequestTiktokPackageVersionOperation : AsyncOperationBase
public string PackageVersion { private set; get; }
public RequestTiktokPackageVersionOperation(TiktokFileSystem fileSystem, int timeout)
public RequestTiktokPackageVersionOperation(TiktokFileSystem fileSystem, bool appendTimeTicks, int timeout)
{
_fileSystem = fileSystem;
_appendTimeTicks = appendTimeTicks;
_timeout = timeout;
}
internal override void InternalStart()
@@ -80,11 +82,19 @@ internal class RequestTiktokPackageVersionOperation : AsyncOperationBase
private string GetRequestURL(string fileName)
{
string url;
// 轮流返回请求地址
if (_requestCount % 2 == 0)
return _fileSystem.RemoteServices.GetRemoteMainURL(fileName);
url = _fileSystem.RemoteServices.GetRemoteMainURL(fileName);
else
return _fileSystem.RemoteServices.GetRemoteFallbackURL(fileName);
url = _fileSystem.RemoteServices.GetRemoteFallbackURL(fileName);
// 在URL末尾添加时间戳
if (_appendTimeTicks)
return $"{url}?{System.DateTime.UtcNow.Ticks}";
else
return url;
}
}
#endif

View File

@@ -121,7 +121,7 @@ internal class TiktokFileSystem : IFileSystem
}
public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout)
{
var operation = new TTFSRequestPackageVersionOperation(this, timeout);
var operation = new TTFSRequestPackageVersionOperation(this, appendTimeTicks, timeout);
return operation;
}
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options)

View File

@@ -11,8 +11,8 @@ internal class RequestWechatPackageVersionOperation : AsyncOperationBase
}
private readonly WechatFileSystem _fileSystem;
private readonly int _timeout;
private readonly bool _appendTimeTicks;
private readonly int _timeout;
private UnityWebTextRequestOperation _webTextRequestOp;
private int _requestCount = 0;
private ESteps _steps = ESteps.None;

View File

@@ -198,6 +198,15 @@ internal class WechatFileSystem : IFileSystem
RemoteServices = new WebRemoteServices(webRoot);
}
// 检查URL双斜杠
// 注意:双斜杠会导致微信插件加载文件失败,但网络请求又不返回失败!
{
var mainURL = RemoteServices.GetRemoteMainURL("test.bundle");
var fallbackURL = RemoteServices.GetRemoteFallbackURL("test.bundle");
if (PathUtility.HasDoubleSlashes(mainURL) || PathUtility.HasDoubleSlashes(fallbackURL))
throw new Exception($"{nameof(RemoteServices)} returned URL contains double slashes. !");
}
_fileSystemMgr = WX.GetFileSystemManager();
}
public virtual void OnDestroy()

View File

@@ -0,0 +1,18 @@
{
"name": "YooAsset.MiniGame",
"rootNamespace": "",
"references": [
"GUID:e34a5702dd353724aa315fb8011f08c3",
"GUID:5efd170ecd8084500bed5692932fe14e",
"GUID:bb21d6197862c4c3e863390dec9859a7"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 839b8c2cb327b8a43afe86fd33563571
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -14,6 +14,11 @@
"description": "YooAsset runtime sample, Include resource update, resource download, resource loading and other functions.",
"path": "Samples~/Space Shooter"
},
{
"displayName": "Mini Game",
"description": "YooAsset extension file system, Include wechat file system, tiktok file system.",
"path": "Samples~/Mini Game"
},
{
"displayName": "Extension Sample",
"description": "YooAsset extension sample, Include patcher combine, patcher compare, patcher importer and other functions.",