pull/229/head
hevinci 2023-12-21 16:18:36 +08:00
parent 0e29e9823d
commit c2a7106221
5 changed files with 142 additions and 243 deletions

View File

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
@ -6,5 +7,13 @@ using UnityEngine;
/// </summary> /// </summary>
public class BuildinFileManifest : ScriptableObject public class BuildinFileManifest : ScriptableObject
{ {
public List<string> BuildinFiles = new List<string>(); [Serializable]
public class Element
{
public string PackageName;
public string FileName;
public string FileCRC32;
}
public List<Element> BuildinFiles = new List<Element>();
} }

View File

@ -1,5 +1,8 @@

public class StreamingAssetsDefine public class StreamingAssetsDefine
{ {
/// <summary>
/// 根目录名称保持和YooAssets资源系统一致
/// </summary>
public const string RootFolderName = "yoo"; public const string RootFolderName = "yoo";
} }

View File

@ -8,63 +8,102 @@ using YooAsset;
/// </summary> /// </summary>
public class GameQueryServices : IBuildinQueryServices public class GameQueryServices : IBuildinQueryServices
{ {
public bool Query(string packageName, string fileName) /// <summary>
{ /// 查询内置文件的时候,是否比对文件哈希值
// 注意fileName包含文件格式 /// </summary>
return StreamingAssetsHelper.FileExists(packageName, fileName); public static bool CompareFileCRC = false;
}
public bool Query(string packageName, string fileName, string fileCRC)
{
// 注意fileName包含文件格式
return StreamingAssetsHelper.FileExists(packageName, fileName, fileCRC);
}
} }
#if UNITY_EDITOR #if UNITY_EDITOR
/// <summary>
/// StreamingAssets目录下资源查询帮助类
/// </summary>
public sealed class StreamingAssetsHelper public sealed class StreamingAssetsHelper
{ {
public static void Init() { } public static void Init() { }
public static bool FileExists(string packageName, string fileName) public static bool FileExists(string packageName, string fileName, string fileCRC)
{ {
string filePath = Path.Combine(Application.streamingAssetsPath, StreamingAssetsDefine.RootFolderName, packageName, fileName); string filePath = Path.Combine(Application.streamingAssetsPath, StreamingAssetsDefine.RootFolderName, packageName, fileName);
return File.Exists(filePath); if (File.Exists(filePath))
} {
if (GameQueryServices.CompareFileCRC)
{
string crc32 = YooAsset.Editor.EditorTools.GetFileCRC32(filePath);
return crc32 == fileCRC;
}
else
{
return true;
}
}
else
{
return false;
}
}
} }
#else #else
/// <summary>
/// StreamingAssets目录下资源查询帮助类
/// </summary>
public sealed class StreamingAssetsHelper public sealed class StreamingAssetsHelper
{ {
private static bool _isInit = false; private class PackageQuery
private static readonly HashSet<string> _cacheData = new HashSet<string>(); {
public readonly Dictionary<string, BuildinFileManifest.Element> Elements = new Dictionary<string, BuildinFileManifest.Element>(1000);
}
/// <summary> private static bool _isInit = false;
/// 初始化 private static readonly Dictionary<string, PackageQuery> _packages = new Dictionary<string, PackageQuery>(10);
/// </summary>
public static void Init()
{
if (_isInit == false)
{
_isInit = true;
var manifest = Resources.Load<BuildinFileManifest>("BuildinFileManifest");
if (manifest != null)
{
foreach (string fileName in manifest.BuildinFiles)
{
_cacheData.Add(fileName);
}
}
}
}
/// <summary> /// <summary>
/// 内置文件查询方法 /// 初始化
/// </summary> /// </summary>
public static bool FileExists(string packageName, string fileName) public static void Init()
{ {
if (_isInit == false) if (_isInit == false)
Init(); {
return _cacheData.Contains(fileName); _isInit = true;
}
var manifest = Resources.Load<BuildinFileManifest>("BuildinFileManifest");
if (manifest != null)
{
foreach (var element in manifest.BuildinFiles)
{
if (_packages.TryGetValue(element.PackageName, out PackageQuery package) == false)
{
package = new PackageQuery();
_packages.Add(element.PackageName, package);
}
package.Elements.Add(element.FileName, element);
}
}
}
}
/// <summary>
/// 内置文件查询方法
/// </summary>
public static bool FileExists(string packageName, string fileName, string fileCRC32)
{
if (_isInit == false)
Init();
if (_packages.TryGetValue(packageName, out PackageQuery package) == false)
return false;
if (package.Elements.TryGetValue(fileName, out var element) == false)
return false;
if (GameQueryServices.CompareFileCRC)
{
return element.FileCRC32 == fileCRC32;
}
else
{
return true;
}
}
} }
#endif #endif
@ -72,42 +111,52 @@ public sealed class StreamingAssetsHelper
#if UNITY_EDITOR #if UNITY_EDITOR
internal class PreprocessBuild : UnityEditor.Build.IPreprocessBuildWithReport internal class PreprocessBuild : UnityEditor.Build.IPreprocessBuildWithReport
{ {
public int callbackOrder { get { return 0; } } public int callbackOrder { get { return 0; } }
/// <summary> /// <summary>
/// 在构建应用程序前处理 /// 在构建应用程序前处理
/// </summary> /// 原理在构建APP之前搜索StreamingAssets目录下的所有资源文件然后将这些文件信息写入内置清单内置清单存储在Resources文件夹下。
public void OnPreprocessBuild(UnityEditor.Build.Reporting.BuildReport report) /// </summary>
{ public void OnPreprocessBuild(UnityEditor.Build.Reporting.BuildReport report)
string saveFilePath = "Assets/Resources/BuildinFileManifest.asset"; {
if (File.Exists(saveFilePath)) string saveFilePath = "Assets/Resources/BuildinFileManifest.asset";
File.Delete(saveFilePath); if (File.Exists(saveFilePath))
{
File.Delete(saveFilePath);
UnityEditor.AssetDatabase.SaveAssets();
UnityEditor.AssetDatabase.Refresh();
}
string folderPath = $"{Application.dataPath}/StreamingAssets/{StreamingAssetsDefine.RootFolderName}"; string folderPath = $"{Application.dataPath}/StreamingAssets/{StreamingAssetsDefine.RootFolderName}";
DirectoryInfo root = new DirectoryInfo(folderPath); DirectoryInfo root = new DirectoryInfo(folderPath);
if (root.Exists == false) if (root.Exists == false)
{ {
Debug.Log($"没有发现YooAsset内置目录 : {folderPath}"); Debug.LogWarning($"没有发现YooAsset内置目录 : {folderPath}");
return; return;
} }
var manifest = ScriptableObject.CreateInstance<BuildinFileManifest>(); var manifest = ScriptableObject.CreateInstance<BuildinFileManifest>();
FileInfo[] files = root.GetFiles("*", SearchOption.AllDirectories); FileInfo[] files = root.GetFiles("*", SearchOption.AllDirectories);
foreach (var fileInfo in files) foreach (var fileInfo in files)
{ {
if (fileInfo.Extension == ".meta") if (fileInfo.Extension == ".meta")
continue; continue;
if (fileInfo.Name.StartsWith("PackageManifest_")) if (fileInfo.Name.StartsWith("PackageManifest_"))
continue; continue;
manifest.BuildinFiles.Add(fileInfo.Name);
}
if (Directory.Exists("Assets/Resources") == false) BuildinFileManifest.Element element = new BuildinFileManifest.Element();
Directory.CreateDirectory("Assets/Resources"); element.PackageName = fileInfo.Directory.Name;
UnityEditor.AssetDatabase.CreateAsset(manifest, saveFilePath); element.FileCRC32 = YooAsset.Editor.EditorTools.GetFileCRC32(fileInfo.FullName);
UnityEditor.AssetDatabase.SaveAssets(); element.FileName = fileInfo.Name;
UnityEditor.AssetDatabase.Refresh(); manifest.BuildinFiles.Add(element);
Debug.Log($"一共{manifest.BuildinFiles.Count}个内置文件,内置资源清单保存成功 : {saveFilePath}"); }
}
if (Directory.Exists("Assets/Resources") == false)
Directory.CreateDirectory("Assets/Resources");
UnityEditor.AssetDatabase.CreateAsset(manifest, saveFilePath);
UnityEditor.AssetDatabase.SaveAssets();
UnityEditor.AssetDatabase.Refresh();
Debug.Log($"一共{manifest.BuildinFiles.Count}个内置文件,内置资源清单保存成功 : {saveFilePath}");
}
} }
#endif #endif

View File

@ -1,151 +0,0 @@
//-------------------------------------
// 作者Stark
//-------------------------------------
using System.Collections.Generic;
using UnityEngine;
using YooAsset;
/*
/// <summary>
/// 资源文件查询服务类
/// </summary>
public class GameQueryServices2 : IBuildinQueryServices
{
public bool QueryStreamingAssets(string packageName, string fileName)
{
return StreamingAssetsHelper2.FileExists($"{StreamingAssetsDefine.RootFolderName}/{packageName}/{fileName}");
}
}
/// <summary>
/// StreamingAssets目录下资源查询帮助类
/// </summary>
public sealed class StreamingAssetsHelper2
{
private static readonly Dictionary<string, bool> _cacheData = new Dictionary<string, bool>(1000);
#if UNITY_ANDROID && !UNITY_EDITOR
private static AndroidJavaClass _unityPlayerClass;
public static AndroidJavaClass UnityPlayerClass
{
get
{
if (_unityPlayerClass == null)
_unityPlayerClass = new UnityEngine.AndroidJavaClass("com.unity3d.player.UnityPlayer");
return _unityPlayerClass;
}
}
private static AndroidJavaObject _currentActivity;
public static AndroidJavaObject CurrentActivity
{
get
{
if (_currentActivity == null)
_currentActivity = UnityPlayerClass.GetStatic<AndroidJavaObject>("currentActivity");
return _currentActivity;
}
}
/// <summary>
/// 利用安卓原生接口查询内置文件是否存在
/// </summary>
public static bool FileExists(string filePath)
{
if (_cacheData.TryGetValue(filePath, out bool result) == false)
{
result = CurrentActivity.Call<bool>("CheckAssetExist", filePath);
_cacheData.Add(filePath, result);
}
return result;
}
#else
public static bool FileExists(string filePath)
{
if (_cacheData.TryGetValue(filePath, out bool result) == false)
{
result = System.IO.File.Exists(System.IO.Path.Combine(Application.streamingAssetsPath, filePath));
_cacheData.Add(filePath, result);
}
return result;
}
#endif
}
#if UNITY_ANDROID && UNITY_EDITOR
/// <summary>
/// 为Github对开发者的友好采用自动补充UnityPlayerActivity.java文件的通用姿势满足各个开发者
/// </summary>
internal class AndroidPost : UnityEditor.Android.IPostGenerateGradleAndroidProject
{
public int callbackOrder => 99;
public void OnPostGenerateGradleAndroidProject(string path)
{
path = path.Replace("\\", "/");
string untityActivityFilePath = $"{path}/src/main/java/com/unity3d/player/UnityPlayerActivity.java";
var readContent = System.IO.File.ReadAllLines(untityActivityFilePath);
string postContent =
" //auto-gen-function \n" +
" public boolean CheckAssetExist(String filePath) \n" +
" { \n" +
" android.content.res.AssetManager assetManager = getAssets(); \n" +
" try \n" +
" { \n" +
" java.io.InputStream inputStream = assetManager.open(filePath); \n" +
" if (null != inputStream) \n" +
" { \n" +
" inputStream.close(); \n" +
" return true; \n" +
" } \n" +
" } \n" +
" catch(java.io.IOException e) \n" +
" { \n" +
" } \n" +
" return false; \n" +
" } \n" +
"}";
if (CheckFunctionExist(readContent) == false)
readContent[readContent.Length - 1] = postContent;
System.IO.File.WriteAllLines(untityActivityFilePath, readContent);
}
private bool CheckFunctionExist(string[] contents)
{
for (int i = 0; i < contents.Length; i++)
{
if (contents[i].Contains("CheckAssetExist"))
{
return true;
}
}
return false;
}
}
#endif
*/
/*
// 以下代码为安卓原生代码,不需要解除注释
//auto-gen-function
public boolean CheckAssetExist(String filePath)
{
android.content.res.AssetManager assetManager = getAssets();
try
{
java.io.InputStream inputStream = assetManager.open(filePath);
if(null != inputStream)
{
inputStream.close();
return true;
}
}
catch(java.io.IOException e)
{
//e.printStackTrace();
}
return false;
}
*/

View File

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