// Copyright (c) 2025 EFramework Innovation. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. using System.IO; using System.Collections.Generic; using UnityEngine; using EFramework.Unity.Utility; namespace EFramework.Unity.Asset { public partial class XAsset { /// /// XAsset.Constants 提供了一些常量定义和运行时环境控制,包括运行配置和 Bundle 名称生成、偏移计算等功能。 /// /// /// /// 功能特性 /// - 运行配置:提供 Bundle 模式、调试模式和资源路径等配置 /// - 名称生成:提供资源路径的处理并生成归一化的 Bundle 名称 /// - 偏移计算:根据首选项中配置的 Bundle 偏移因子计算文件的偏移 /// /// 使用手册 /// 1. 运行配置 /// - 配置项:Bundle 模式 /// 配置说明:控制是否启用 Bundle 模式 /// 依赖条件:编辑器模式下需要启用模拟模式 /// 访问方式: /// /// var isBundleMode = XAsset.Constants.BundleMode; /// /// /// - 配置项:引用计数模式 /// 配置说明:控制是否启用引用计数模式 /// 依赖条件:仅在 Bundle 模式下可用 /// 访问方式: /// /// var isReferMode = XAsset.Constants.ReferMode; /// /// /// - 配置项:调试模式 /// 配置说明:控制是否启用调试模式 /// 依赖条件:仅在 Bundle 模式下可用 /// 访问方式: /// /// var isDebugMode = XAsset.Constants.DebugMode; /// /// /// - 配置项:本地路径 /// 配置说明:获取资源文件的本地存储路径 /// 访问方式: /// /// var localPath = XAsset.Constants.LocalPath; /// /// /// 2. 名称生成 /// - 配置项:默认扩展名 /// /// XAsset.Constants.Extension = ".bundle"; /// /// /// - 配置项:生成规则 /// 生成资源名称的规则如下: /// 1. 将资源路径的 `Assets/` 剔除 /// 2. 获取资源的拓展名,若为空或 `.unity` 则不处理,否则剔除拓展名 /// 3. 归一化路径并转为全小写,避免路径的大小写问题 /// 4. 对归一化的路径进行 `MD5` 求值并追加 `XAsset.Constants.Extension` 扩展名 /// /// 使用示例: /// /// var assetPath = "Resources/Example/Test.prefab"; /// var bundleName = XAsset.Constants.GetName(assetPath); /// /// /// 3. 偏移计算 /// - 配置项:偏移因子 /// 配置说明:控制 Bundle 文件偏移的计算因子 /// 依赖条件:通过首选项配置 `XPrefs.GetInt(Preferences.OffsetFactor)` /// 默认值:从 `Preferences.OffsetFactorDefault` 获取 /// /// - 配置项:计算方法 /// 偏移计算的规则如下: /// 1. 如果 Bundle 名称为空,返回 0 /// 2. 如果偏移因子小于等于 0,返回 0 /// 3. 计算公式:`(bundleName.Length % offsetFactor + 1) * 28` /// /// 使用示例: /// /// var bundleName = XAsset.Constants.GetName(assetPath); /// var offset = XAsset.Constants.GetOffset(bundleName); /// /// /// 更多信息请参考模块文档。 /// public partial class Constants { #region 运行配置 /// /// Manifest 表示 AssetBundleManifest 的默认文件名。 /// public static string Manifest = "Assets"; /// /// bBundleMode 是 Bundle 模式的初始化标记。 /// internal static bool bBundleMode; /// /// bundleMode 是 Bundle 模式的当前状态。 /// internal static bool bundleMode; /// /// BundleMode 获取资源系统当前是否运行在 Bundle 模式下。 /// Bundle 模式下会从打包的资源文件中加载资源,而不是直接从 Assets 目录加载,这个设置会受到编辑器状态和模拟模式的影响。 /// public static bool BundleMode { get { if (!bBundleMode) { bBundleMode = true; bundleMode = XPrefs.GetBool(Preferences.BundleMode, Preferences.BundleModeDefault) && (!Application.isEditor || XPrefs.GetBool(Preferences.SimulateMode)); } return bundleMode; } } /// /// bReferMode 是引用模式的初始化标记。 /// internal static bool bReferMode; /// /// referMode 是引用模式的当前状态。 /// internal static bool referMode; /// /// ReferMode 获取是否启用了引用计数模式。 /// 在引用计数模式下,系统会跟踪资源的使用情况,只有当资源不再被任何对象引用时才会被卸载,这个模式需要 Bundle 模式开启才能生效。 /// public static bool ReferMode { get { if (!bReferMode) { bReferMode = true; referMode = BundleMode && XPrefs.GetBool(Preferences.ReferMode, Preferences.ReferModeDefault); } return referMode; } } /// /// bDebugMode 是调试模式的初始化标记。 /// internal static bool bDebugMode; /// /// debugMode 是调试模式的当前状态。 /// internal static bool debugMode; /// /// DebugMode 获取是否启用了调试模式。 /// 调试模式下会输出详细的日志信息,帮助开发者追踪资源加载和卸载的过程,这个模式同样需要 Bundle 模式开启才能生效。 /// public static bool DebugMode { get { if (!bDebugMode) { bDebugMode = true; debugMode = BundleMode && XPrefs.GetBool(Preferences.DebugMode); } return debugMode; } } /// /// bLocalPath 是本地路径的初始化标记。 /// internal static bool bLocalPath; /// /// localPath 是缓存的本地路径。 /// internal static string localPath; /// /// LocalPath 获取资源文件的本地存储路径。 /// 这个路径用于存放下载或解压后的资源文件,路径格式会根据当前平台和配置自动调整。 /// public static string LocalPath { get { if (!bLocalPath) { bLocalPath = true; localPath = XFile.PathJoin(XEnv.LocalPath, XPrefs.GetString(Preferences.LocalUri, Preferences.LocalUriDefault)); } return localPath; } } #endregion #region 生成名称 /// /// Extension 是资源包文件的默认扩展名,用于标识打包后的资源文件。 /// public static string Extension = ".bundle"; /// /// nameCache 是资源名称的缓存,用于提高重复名称生成的性能。 /// internal static readonly Dictionary nameCache = new(); /// /// GetName 根据资源路径生成唯一的资源包名称。 /// /// 需要转换的资源路径 /// 转换后的资源名称,包括扩展名 public static string GetName(string assetPath) { if (string.IsNullOrEmpty(assetPath)) return string.Empty; if (nameCache.TryGetValue(assetPath, out var bundleName)) return bundleName; else { if (assetPath.StartsWith("Assets/")) assetPath = assetPath["Assets/".Length..]; var extension = Path.GetExtension(assetPath); if (!string.IsNullOrEmpty(extension) && extension != ".unity") // 场景文件只能单独打包 { assetPath = assetPath.Replace(extension, ""); } bundleName = XFile.NormalizePath(assetPath).ToLower().MD5() + Extension; nameCache[assetPath] = bundleName; return bundleName; } } #endregion #region 计算偏移 /// /// bOffsetFactor 是 offsetFactor 的初始化标记。 /// internal static bool bOffsetFactor; /// /// offsetFactor 是 Bundle 文件偏移的缓存值。 /// internal static int offsetFactor; /// /// GetOffset 根据首选项中配置的 Bundle 偏移因子计算文件的偏移。 /// /// 需要计算文件偏移的 Bundle 名称 /// Bundle 文件偏移 public static ulong GetOffset(string bundleName) { if (string.IsNullOrEmpty(bundleName)) return 0; if (!bOffsetFactor) { bOffsetFactor = true; offsetFactor = XPrefs.GetInt(Preferences.OffsetFactor, Preferences.OffsetFactorDefault); } if (offsetFactor <= 0) return 0; return (ulong)((bundleName.Length % offsetFactor + 1) * 28); } #endregion } } }