This commit is contained in:
2026-06-12 17:14:59 +08:00
parent 84a14c06bd
commit b768474e67
51 changed files with 1011 additions and 391 deletions
@@ -0,0 +1,188 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using SGModule.Common.Helper;
using UnityEditor;
using UnityEditor.PackageManager;
using UnityEditor.PackageManager.Requests;
using PackageInfo = UnityEditor.PackageManager.PackageInfo;
#if USE_ADDRESSABLES
using UnityEditor.AddressableAssets;
#endif
namespace SGModule.Editor {
[InitializeOnLoad]
public static class AddressablesManager {
private const string AddressablesPackageName = "com.unity.addressables";
private const string AddressablesSymbol = "USE_ADDRESSABLES";
private static AddRequest _addRequest;
// 安装标记,避免重复弹窗
private static bool _isInstallingAddressables;
static AddressablesManager() {
EditorApplication.projectChanged += OnProjectChanged; // 监听项目变更
CheckAndSetupAddressables();
}
private static string DefaultConfigsPath => "Assets/Configs"; // 默认的 Addressables 配置路径
private static void CheckAndSetupAddressables() {
if (IsAddressablesInstalled()) {
Log.Info("ConfigLoader", "Addressables 已安装,正在初始化...");
AddScriptingDefineSymbol(AddressablesSymbol);
#if USE_ADDRESSABLES
EnsureAddressablesConfigured();
#endif
}
else {
RemoveScriptingDefineSymbol(AddressablesSymbol);
if (!_isInstallingAddressables) {
PromptToInstallAddressables();
}
}
}
private static bool IsAddressablesInstalled() {
return PackageInfo.GetAllRegisteredPackages().Any(package => package.name == AddressablesPackageName);
}
private static void PromptToInstallAddressables() {
var install = EditorUtility.DisplayDialog(
"Addressables 未安装",
"当前插件依赖 Addressables 功能,请安装以确保正常使用。\n\n是否立即安装 Addressables",
"安装",
"取消");
if (install) {
InstallAddressables();
}
else {
Log.Warning("ConfigLoader", "用户取消安装 Addressables,部分功能可能无法正常使用!");
}
}
private static void InstallAddressables() {
if (_isInstallingAddressables) {
return; // 防止重复安装
}
Log.Info("ConfigLoader", "开始安装 Addressables...");
_isInstallingAddressables = true; // 标记正在安装,避免重复弹窗
_addRequest = Client.Add(AddressablesPackageName);
EditorApplication.update += MonitorAddRequest;
}
private static void MonitorAddRequest() {
if (_addRequest == null || !_addRequest.IsCompleted) {
return;
}
EditorApplication.update -= MonitorAddRequest;
if (_addRequest.Status == StatusCode.Success) {
Log.Info("ConfigLoader", "Addressables 安装成功!");
EditorUtility.DisplayDialog("安装完成", "Addressables 安装成功,请稍候等待 Unity 刷新。", "确定");
CheckAndSetupAddressables();
}
else if (_addRequest.Status >= StatusCode.Failure) {
Log.Error("ConfigLoader", $"安装 Addressables 失败:{_addRequest.Error.message}");
EditorUtility.DisplayDialog("安装失败", $"安装 Addressables 失败:{_addRequest.Error.message}", "确定");
}
_isInstallingAddressables = false; // 重置标记
}
private static void AddScriptingDefineSymbol(string symbol) {
var symbols = new List<string>(PlayerSettings
.GetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup).Split(';'));
if (symbols.Contains(symbol)) {
return;
}
symbols.Add(symbol);
PlayerSettings.SetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup,
string.Join(";", symbols));
Log.Info("ConfigLoader", $"已添加脚本定义符号: {symbol}");
}
private static void RemoveScriptingDefineSymbol(string symbol) {
var symbols = new List<string>(PlayerSettings
.GetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup).Split(';'));
if (symbols.Contains(symbol)) {
symbols.Remove(symbol);
PlayerSettings.SetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup,
string.Join(";", symbols));
Log.Info("ConfigLoader", $"已移除脚本定义符号: {symbol}");
}
}
private static void OnProjectChanged() {
Log.Info("ConfigLoader", "检测到项目变更,重新检查 Addressables 状态...");
CheckAndSetupAddressables();
}
#if USE_ADDRESSABLES
private static void EnsureAddressablesConfigured() {
var settings = AddressableAssetSettingsDefaultObject.Settings;
if (settings == null) {
Log.Info("ConfigLoader", "正在初始化 Addressables 设置...");
settings = AddressableAssetSettingsDefaultObject.GetSettings(true); // 自动创建配置
}
// 确保默认的 Configs 文件夹存在并被添加到 Addressables
var needRefresh = false;
if (!Directory.Exists(DefaultConfigsPath)) {
Directory.CreateDirectory(DefaultConfigsPath);
Log.Info("ConfigLoader", $"已创建文件夹: {DefaultConfigsPath}");
needRefresh = true;
}
if (!IsFolderInAddressables(DefaultConfigsPath)) {
var guid = AssetDatabase.AssetPathToGUID(DefaultConfigsPath);
var group = settings.DefaultGroup;
settings.CreateOrMoveEntry(guid, group)?.SetLabel("config", true, true);
needRefresh = true;
}
if (needRefresh) {
AssetDatabase.Refresh();
}
}
private static bool IsFolderInAddressables(string folderPath) {
var settings = AddressableAssetSettingsDefaultObject.Settings;
foreach (var group in settings.groups)
{
if (group)
{
foreach (var entry in group.entries)
{
if (AssetDatabase.GUIDToAssetPath(entry.guid) == folderPath)
{
return true;
}
}
}
}
return false;
}
#endif
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 383ac67f695b4c6e94ba988c9303cd5b
timeCreated: 1733734050
@@ -3,10 +3,8 @@ using System.IO;
using SGModule.Common.Helper;
using UnityEngine;
namespace SGModule.ConfigLoader
{
public class ConfigFileManager
{
namespace SGModule.ConfigLoader {
public class ConfigFileManager {
private const int MaxErrorCount = 6;
private const string ConfigFileNameKey = "ConfigFileName";
private const string FirstLaunchKey = "FirstLaunch";
@@ -17,59 +15,44 @@ namespace SGModule.ConfigLoader
private static bool IsFirstLaunch => !PlayerPrefs.HasKey(FirstLaunchKey);
private static string SavedConfigFileName => PlayerPrefs.GetString(ConfigFileNameKey);
private static void SetFirstLaunch()
{
private static void SetFirstLaunch() {
PlayerPrefs.SetInt(FirstLaunchKey, 1);
}
private static void SetSavedConfigFileName(string name)
{
private static void SetSavedConfigFileName(string name) {
PlayerPrefs.SetString(ConfigFileNameKey, name);
}
private void IncrementErrorCount()
{
private void IncrementErrorCount() {
_initConfigErrorCount++;
}
// 检查是否需要下载新配置,基于传入的期望配置文件名setting
private static bool HasNewConfig(string expectedSetting)
{
if (string.IsNullOrEmpty(SavedConfigFileName))
{
private static bool HasNewConfig(string expectedSetting) {
if (string.IsNullOrEmpty(SavedConfigFileName)) {
return true;
}
return !SavedConfigFileName.Equals(expectedSetting);
}
private void FirstLaunchCopyConfig(Action<bool> callback)
{
private void FirstLaunchCopyConfig(Action<bool> callback) {
SetFirstLaunch();
Debug.Log("000000000000000000000000000000");
FileNetworkManager.Instance.CopyStreamingAssetsToPersistentDataPath(result =>
{
Debug.Log("0000000000000000000000000000006");
FileNetworkManager.Instance.CopyStreamingAssetsToPersistentDataPath(result => {
var isSuccess = false;
if (result)
{
Debug.Log("0000000000000000000000000000007");
if (result) {
var names = FileNetworkManager.Instance.GetFileNamesFromPersistentDataPath(FileNetworkManager.FolderName);
if (names.Length > 0)
{
Debug.Log("0000000000000000000000000000008");
Debug.Log("0000000000000000000000000000009"+names[0]);
if (names.Length > 0) {
SetSavedConfigFileName(names[0]);
isSuccess = true;
}
}
else
{
else {
Log.ConfigLoader.Error("拷贝文件失败 请检查Configs文件夹是否有配置文件");
}
if (!isSuccess)
{
if (!isSuccess) {
IncrementErrorCount();
}
@@ -77,20 +60,16 @@ namespace SGModule.ConfigLoader
});
}
private void DownloadConfig(string cdnUrl, string setting, Action<bool, string> callback)
{
private void DownloadConfig(string cdnUrl, string setting, Action<bool, string> callback) {
var url = $"{cdnUrl}/config/{setting}";
Log.ConfigLoader.Info($"开始下载配置文件 {url}", false);
FileNetworkManager.Instance.ReadData(url, result =>
{
if (!string.IsNullOrEmpty(result))
{
FileNetworkManager.Instance.ReadData(url, result => {
if (!string.IsNullOrEmpty(result)) {
SetSavedConfigFileName(setting);
FileNetworkManager.Instance.WriteToPersistentData(FileNetworkManager.Instance.GetConfigFOlderPath(), setting, result);
callback?.Invoke(true, result);
}
else
{
else {
Log.ConfigLoader.Error("下载配置文件失败");
IncrementErrorCount();
callback?.Invoke(false, null);
@@ -98,92 +77,40 @@ namespace SGModule.ConfigLoader
});
}
private void ReadLocalConfig(Action<bool, string> callback)
{
private void ReadLocalConfig(Action<bool, string> callback) {
var savedCfgName = SavedConfigFileName;
Log.ConfigLoader.Info($"开始读取本地配置文件 {savedCfgName}", false);
if (string.IsNullOrEmpty(savedCfgName))
{
if (string.IsNullOrEmpty(savedCfgName)) {
IncrementErrorCount();
callback?.Invoke(false, null);
return;
}
var path = Path.Combine(FileNetworkManager.Instance.GetConfigFOlderPath(), savedCfgName);
bool have_config = false;
if (Directory.Exists(FileNetworkManager.Instance.GetConfigFOlderPath()))
{
// 获取该目录下的所有文件
string[] files = Directory.GetFiles(FileNetworkManager.Instance.GetConfigFOlderPath());
if (files.Length > 0)
{
Debug.Log("文件夹下有文件");
have_config = true;
FileNetworkManager.Instance.ReadData(path, result => {
if (!string.IsNullOrEmpty(result)) {
callback?.Invoke(true, result);
}
else
{
Debug.Log("文件夹为空");
else {
Log.ConfigLoader.Error("读取本地数据异常");
IncrementErrorCount();
callback?.Invoke(false, null);
}
}
else
{
Debug.Log("文件夹不存在");
}
if (have_config)
{
FileNetworkManager.Instance.ReadData(path, result =>
{
if (!string.IsNullOrEmpty(result))
{
callback?.Invoke(true, result);
}
else
{
Log.ConfigLoader.Error("读取本地数据异常");
IncrementErrorCount();
callback?.Invoke(false, null);
}
});
}
else
{
Debug.Log(savedCfgName);
FirstLaunchCopyConfig(success =>
{
path = Path.Combine(FileNetworkManager.Instance.GetConfigFOlderPath(), SavedConfigFileName);
FileNetworkManager.Instance.ReadData(path, result =>
{
if (!string.IsNullOrEmpty(result))
{
callback?.Invoke(true, result);
}
});
});
}
});
}
/// <summary>
/// 配置文件检查与加载流程
/// </summary>
public void CheckAndLoadConfig(ConfigInitOptions initOptions, Action<string> onConfigLoaded, Action<ConfigLoaderState> callback)
{
if (HasExceededMaxErrors)
{
public void CheckAndLoadConfig(ConfigInitOptions initOptions, Action<string> onConfigLoaded, Action<ConfigLoaderState> callback) {
if (HasExceededMaxErrors) {
callback?.Invoke(ConfigLoaderState.Failed);
return;
}
Debug.Log("是否第一次登录"+IsFirstLaunch);
if (IsFirstLaunch)
{
FirstLaunchCopyConfig(success =>
{
if (!success)
{
if (IsFirstLaunch) {
FirstLaunchCopyConfig(success => {
if (!success) {
IncrementErrorCount();
}
@@ -191,25 +118,18 @@ Debug.Log("是否第一次登录"+IsFirstLaunch);
});
return;
}
Debug.Log("是否需要下载"+HasNewConfig(initOptions.Setting));
if (HasNewConfig(initOptions.Setting))
{
DownloadConfig(initOptions.CdnUrl, initOptions.Setting, (success, json) =>
{
if (success)
{
if (HasNewConfig(initOptions.Setting)) {
DownloadConfig(initOptions.CdnUrl, initOptions.Setting, (success, json) => {
if (success) {
ReloadConfig(json, onConfigLoaded, callback);
}
else
{
ReadLocalConfig((readSuccess, localJson) =>
{
if (readSuccess)
{
else {
ReadLocalConfig((readSuccess, localJson) => {
if (readSuccess) {
ReloadConfig(localJson, onConfigLoaded, callback);
}
else
{
else {
callback?.Invoke(ConfigLoaderState.Failed);
}
});
@@ -218,18 +138,13 @@ Debug.Log("是否需要下载"+HasNewConfig(initOptions.Setting));
return;
}
ReadLocalConfig((success, json) =>
{
if (success)
{
ReadLocalConfig((success, json) => {
if (success) {
ReloadConfig(json, onConfigLoaded, callback);
}
else
{
FirstLaunchCopyConfig(result =>
{
if (!result)
{
else {
FirstLaunchCopyConfig(result => {
if (!result) {
IncrementErrorCount();
}
@@ -239,10 +154,8 @@ Debug.Log("是否需要下载"+HasNewConfig(initOptions.Setting));
});
}
private static void ReloadConfig(string json, Action<string> onConfigLoaded, Action<ConfigLoaderState> callback)
{
if (string.IsNullOrWhiteSpace(json))
{
private static void ReloadConfig(string json, Action<string> onConfigLoaded, Action<ConfigLoaderState> callback) {
if (string.IsNullOrWhiteSpace(json)) {
callback?.Invoke(ConfigLoaderState.JsonEmptyError);
return;
}
@@ -6,9 +6,9 @@ using System.Linq;
using SGModule.Common.Base;
using SGModule.Common.Helper;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;
using System.Threading.Tasks;
using UnityEngine.ResourceManagement.AsyncOperations;
#if UNITY_EDITOR
using UnityEditor;
#endif
@@ -16,53 +16,42 @@ using UnityEditor;
#if USE_ADDRESSABLES
#endif
namespace SGModule.ConfigLoader
{
public class FileNetworkManager : SingletonMonoBehaviour<FileNetworkManager>
{
namespace SGModule.ConfigLoader {
public class FileNetworkManager : SingletonMonoBehaviour<FileNetworkManager> {
public const string FolderName = "Configs";
private const string FolderLabel = "config";
private string _configFolderPath;
protected override void Awake()
{
protected override void Awake() {
base.Awake();
_configFolderPath = Path.Combine(Application.persistentDataPath, FolderName);
}
public string GetConfigFOlderPath()
{
public string GetConfigFOlderPath() {
return _configFolderPath;
}
// 示例解析文件列表方法(你可以根据实际需求实现)
private List<string> ParseFileList(string data)
{
private List<string> ParseFileList(string data) {
// 假设 data 是文件列表的文本,解析文件名
// 根据实际情况解析,例如通过换行符分割
return data.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries).ToList();
}
public void CopyStreamingAssetsToPersistentDataPath(Action<bool> onComplete = null)
{
Debug.Log("0000000000000000000000000000001");
public void CopyStreamingAssetsToPersistentDataPath(Action<bool> onComplete = null) {
// 如果目标文件夹不存在,创建它
if (!Directory.Exists(_configFolderPath))
{
if (!Directory.Exists(_configFolderPath)) {
Directory.CreateDirectory(_configFolderPath);
}
Debug.Log("0000000000000000000000000000002");
// CopyFile(onComplete);
StartCoroutine(CopyFile(onComplete));
}
private void HandleInitializationError()
{
private void HandleInitializationError() {
// 检查文件是否存在
var path = $"{Application.dataPath}/Library/com.unity.addressables/aa/Android/settings.json";
if (!File.Exists(path))
{
if (!File.Exists(path)) {
Log.ConfigLoader.Warning(
$"Settings file not found at: {path}. Rebuilding Addressables may be required.");
}
@@ -71,104 +60,68 @@ namespace SGModule.ConfigLoader
// 提示用户或执行其他逻辑
// 比如:显示弹窗或退出程序
}
private IEnumerator CopyFile(Action<bool> onComplete = null)
{
Debug.Log("开始加载 Configs 文件夹");
TextAsset[] files = Resources.LoadAll<TextAsset>("Configs");
private IEnumerator CopyFile(Action<bool> onComplete = null) {
#if USE_ADDRESSABLES
var handle = Addressables.LoadResourceLocationsAsync(FolderLabel);
if (files.Length > 0)
{
TextAsset jsonFile = files[0];
string jsonFileName = jsonFile.name;
yield return handle;
Log.ConfigLoader.Info($"Loaded JSON Name:{jsonFileName} content: " + jsonFile.text);
if (handle.Status == AsyncOperationStatus.Succeeded) {
// 查找以 ".json" 结尾的文件
var jsonLocation = handle.Result.FirstOrDefault(loc => loc.PrimaryKey.EndsWith(".json"));
if (!Directory.Exists(_configFolderPath))
Directory.CreateDirectory(_configFolderPath);
if (jsonLocation != null) {
var jsonFileName = Path.GetFileName(jsonLocation.PrimaryKey);
// 加载 JSON 文件
var textAssetAsync = Addressables.LoadAssetAsync<TextAsset>(jsonLocation);
var destFilePath = Path.Combine(_configFolderPath, jsonFileName + ".json");
yield return textAssetAsync;
// 同步写入文件
File.WriteAllBytes(destFilePath, jsonFile.bytes);
// 等待一帧再执行回调,保持协程风格
yield return null;
onComplete?.Invoke(true);
}
else
{
Log.ConfigLoader.Error("Resources/Configs 下没有找到任何 TextAsset 文件");
yield return null;
onComplete?.Invoke(false);
}
}
// private IEnumerable CopyFile(Action<bool> onComplete = null)
// {
if (textAssetAsync.Status == AsyncOperationStatus.Succeeded) {
var jsonFile = textAssetAsync.Result;
Log.ConfigLoader.Info($"Loaded JSON Name:{jsonFileName} content: " + jsonFile.text);
// // if (handle.Status == AsyncOperationStatus.Succeeded) {
// // 查找以 ".json" 结尾的文件
// // var jsonLocation = handle.Result.FirstOrDefault(loc => loc.PrimaryKey.EndsWith(".json"));
var destFilePath = Path.Combine(_configFolderPath, jsonFileName);
File.WriteAllBytes(destFilePath, jsonFile.bytes);
onComplete?.Invoke(true);
}
else {
Log.ConfigLoader.Error("Failed to load JSON file");
// // if (jsonLocation != null) {
// // var jsonFileName = Path.GetFileName(jsonLocation.PrimaryKey);
// // 加载 JSON 文件
// // var textAssetAsync = Addressables.LoadAssetAsync<TextAsset>(jsonLocation);
// Debug.Log("0000000000000000000000000000003");
// TextAsset[] files = Resources.LoadAll<TextAsset>("Configs");
// // yield return textAssetAsync;
onComplete?.Invoke(false);
}
}
else {
Log.ConfigLoader.Error("No JSON file found in folder");
// // if (textAssetAsync.Status == AsyncOperationStatus.Succeeded)
// // {
// TextAsset jsonFile = files[0];
// string jsonFileName = jsonFile.name;
// Log.ConfigLoader.Info($"Loaded JSON Name:{jsonFileName} content: " + jsonFile.text);
onComplete?.Invoke(false);
}
}
else {
Log.ConfigLoader.Error("Failed to load folder resources");
// Debug.Log("0000000000000000000000000000004");
// var destFilePath = Path.Combine(_configFolderPath, jsonFileName);
// File.WriteAllBytes(destFilePath, jsonFile.bytes);
// Debug.Log("0000000000000000000000000000005");
// onComplete?.Invoke(true);
onComplete?.Invoke(false);
}
#else
Log.Error( "没有 Addressables 插件,请检查 ");
yield break;
#endif
}
// // }
// // else {
// // Log.ConfigLoader.Error("Failed to load JSON file");
// // onComplete?.Invoke(false);
// // }
// // }
// // else {
// // Log.ConfigLoader.Error("No JSON file found in folder");
// // onComplete?.Invoke(false);
// // }
// // }
// // else
// // {
// // Log.ConfigLoader.Error("Failed to load folder resources");
// // onComplete?.Invoke(false);
// // }
// }
private IEnumerator CopyFile(string sourceFile, string destFile, Action<bool> onComplete = null)
{
private IEnumerator CopyFile(string sourceFile, string destFile, Action<bool> onComplete = null) {
var filePath = "file://" + sourceFile;
using (var www = UnityWebRequest.Get(filePath))
{
using (var www = UnityWebRequest.Get(filePath)) {
yield return www.SendWebRequest();
if (www.result == UnityWebRequest.Result.Success)
{
if (www.result == UnityWebRequest.Result.Success) {
File.WriteAllBytes(destFile, www.downloadHandler.data);
Log.ConfigLoader.Info($"File copied to {destFile}");
onComplete?.Invoke(true);
}
else
{
else {
Log.ConfigLoader.Error("Failed to copy file: " + www.error);
onComplete?.Invoke(false);
@@ -181,8 +134,7 @@ namespace SGModule.ConfigLoader
/// </summary>
/// <param name="path"></param>
/// <param name="callback"></param>
public void ReadData(string path, Action<string> callback)
{
public void ReadData(string path, Action<string> callback) {
StartCoroutine(ReadDataEnumerator(path, callback));
}
@@ -192,17 +144,14 @@ namespace SGModule.ConfigLoader
/// <param name="path"></param>
/// <param name="callback"></param>
/// <returns></returns>
private IEnumerator ReadDataEnumerator(string path, Action<string> callback)
{
private IEnumerator ReadDataEnumerator(string path, Action<string> callback) {
string fullPath;
// 判断是网络URL还是本地文件路径
if (path.StartsWith("http://") || path.StartsWith("https://"))
{
if (path.StartsWith("http://") || path.StartsWith("https://")) {
fullPath = path; // 网络URL
#if UNITY_EDITOR
if (path.StartsWith("http://") && PlayerSettings.insecureHttpOption == InsecureHttpOption.NotAllowed)
{
if (path.StartsWith("http://") && PlayerSettings.insecureHttpOption == InsecureHttpOption.NotAllowed) {
Log.ConfigLoader.Error("发起了 HTTP 链接,但设置了不允许非Https连接,请检查设置!!!");
callback?.Invoke(null);
@@ -210,26 +159,22 @@ namespace SGModule.ConfigLoader
}
#endif
}
else
{
else {
// 本地文件路径
fullPath = "file://" + path;
}
Debug.Log(fullPath);
// 使用UnityWebRequest读取数据
using (var webRequest = UnityWebRequest.Get(fullPath))
{
using (var webRequest = UnityWebRequest.Get(fullPath)) {
yield return webRequest.SendWebRequest();
if (webRequest.result == UnityWebRequest.Result.ConnectionError ||
webRequest.result == UnityWebRequest.Result.ProtocolError)
{
webRequest.result == UnityWebRequest.Result.ProtocolError) {
Log.ConfigLoader.Error($"Error while reading file: {webRequest.error} path: {fullPath}");
callback?.Invoke(null); // 返回null表示出错
}
else
{
else {
var data = webRequest.downloadHandler.text;
callback?.Invoke(data); // 通过回调传出数据
}
@@ -242,21 +187,18 @@ Debug.Log(fullPath);
/// <param name="folderName">文件夹名称</param>
/// <param name="fileName">文件名称</param>
/// <param name="content">要写入的内容</param>
public void WriteToPersistentData(string folderName, string fileName, string content)
{
public void WriteToPersistentData(string folderName, string fileName, string content) {
// 获取持久化数据路径
var folderPath = Path.Combine(Application.persistentDataPath, folderName);
// 如果文件夹不存在,则创建它
if (!Directory.Exists(folderPath))
{
if (!Directory.Exists(folderPath)) {
Directory.CreateDirectory(folderPath);
}
// 删除原有文件
var existingFiles = Directory.GetFiles(folderPath);
foreach (var file in existingFiles)
{
foreach (var file in existingFiles) {
File.Delete(file);
}
@@ -275,12 +217,11 @@ Debug.Log(fullPath);
/// </summary>
/// <param name="subdirectory"></param>
/// <returns></returns>
public string[] GetFileNamesFromPersistentDataPath(string subdirectory)
{
public string[] GetFileNamesFromPersistentDataPath(string subdirectory) {
var directoryPath = Path.Combine(Application.persistentDataPath, subdirectory);
if (Directory.Exists(directoryPath))
// 获取目录中的所有文件名
// 获取目录中的所有文件名
{
return Directory.GetFiles(directoryPath)
.Select(Path.GetFileName) // 只提取文件名