├── FuXi ├── Bridge.meta ├── Bridge │ ├── Editor.meta │ └── Editor │ │ ├── EditorExtension.cs │ │ ├── EditorExtension.cs.meta │ │ ├── EditorInternalBridge.asmdef │ │ ├── EditorInternalBridge.asmdef.meta │ │ ├── ProjectBrowserExtension.cs │ │ └── ProjectBrowserExtension.cs.meta ├── CHANGELOG.md ├── CHANGELOG.md.meta ├── Editor.meta ├── Editor │ ├── AssembleInfo.cs │ ├── AssembleInfo.cs.meta │ ├── BuildPipeline.meta │ ├── BuildPipeline │ │ ├── BuildBundleProcess.cs │ │ ├── BuildBundleProcess.cs.meta │ │ ├── BuildPlayerProcess.cs │ │ ├── BuildPlayerProcess.cs.meta │ │ ├── IBuild.cs │ │ └── IBuild.cs.meta │ ├── Data.meta │ ├── Data │ │ ├── Fx_BuildAsset.cs │ │ ├── Fx_BuildAsset.cs.meta │ │ ├── Fx_BuildPackage.cs │ │ ├── Fx_BuildPackage.cs.meta │ │ ├── Fx_BuildSetting.cs │ │ └── Fx_BuildSetting.cs.meta │ ├── Fx_Command.cs │ ├── Fx_Command.cs.meta │ ├── Fx_CreateMenu.cs │ ├── Fx_CreateMenu.cs.meta │ ├── Fx_Editor.asmdef │ ├── Fx_Editor.asmdef.meta │ ├── Fx_EditorConfigs.cs │ ├── Fx_EditorConfigs.cs.meta │ ├── Fx_InitializeBeforeSceneLoad.cs │ ├── Fx_InitializeBeforeSceneLoad.cs.meta │ ├── Fx_Style.cs │ ├── Fx_Style.cs.meta │ ├── Helper.meta │ ├── Helper │ │ ├── BuildHelper.cs │ │ ├── BuildHelper.cs.meta │ │ ├── DoCreateFuXiBuildAsset.cs │ │ ├── DoCreateFuXiBuildAsset.cs.meta │ │ ├── DoCreateFuXiBuildPackage.cs │ │ ├── DoCreateFuXiBuildPackage.cs.meta │ │ ├── Fx_PlayerName.cs │ │ ├── Fx_PlayerName.cs.meta │ │ ├── IBuildPreprocess.cs │ │ ├── IBuildPreprocess.cs.meta │ │ ├── IPlayerNameDefine.cs │ │ ├── IPlayerNameDefine.cs.meta │ │ ├── ProcessingHelper.cs │ │ └── ProcessingHelper.cs.meta │ ├── Inspector.meta │ ├── Inspector │ │ ├── Fx_BuildAssetInspector.cs │ │ ├── Fx_BuildAssetInspector.cs.meta │ │ ├── Fx_BuildPackageInspector.cs │ │ ├── Fx_BuildPackageInspector.cs.meta │ │ ├── Fx_BuildSettingInspector.cs │ │ └── Fx_BuildSettingInspector.cs.meta │ ├── Resources.meta │ ├── Resources │ │ ├── Fx_ReferenceView.jpg │ │ ├── Fx_ReferenceView.jpg.meta │ │ ├── Gizmos.meta │ │ ├── Gizmos │ │ │ ├── Fx_About.png │ │ │ ├── Fx_About.png.meta │ │ │ ├── Fx_Asset Black.png │ │ │ ├── Fx_Asset Black.png.meta │ │ │ ├── Fx_Asset.png │ │ │ ├── Fx_Asset.png.meta │ │ │ ├── Fx_AssetPackage.png │ │ │ ├── Fx_AssetPackage.png.meta │ │ │ ├── Fx_PathMenu.png │ │ │ ├── Fx_PathMenu.png.meta │ │ │ ├── Fx_Setting.png │ │ │ └── Fx_Setting.png.meta │ │ ├── Images.meta │ │ ├── Images │ │ │ ├── Label_Bottom_Line.png │ │ │ └── Label_Bottom_Line.png.meta │ │ ├── Uss.meta │ │ └── Uss │ │ │ ├── Fx_BuildAsset.uss │ │ │ ├── Fx_BuildAsset.uss.meta │ │ │ ├── Fx_BundleReferenceWindow.uss │ │ │ ├── Fx_BundleReferenceWindow.uss.meta │ │ │ ├── Fx_CommonInspector.uss │ │ │ ├── Fx_CommonInspector.uss.meta │ │ │ ├── Fx_VersionManagerWindow.uss │ │ │ └── Fx_VersionManagerWindow.uss.meta │ ├── Simulation.meta │ ├── Simulation │ │ ├── FxEditorAsset.cs │ │ ├── FxEditorAsset.cs.meta │ │ ├── FxEditorRawAsset.cs │ │ ├── FxEditorRawAsset.cs.meta │ │ ├── FxEditorScene.cs │ │ └── FxEditorScene.cs.meta │ ├── Window.meta │ └── Window │ │ ├── Fx_AssetView.cs │ │ ├── Fx_AssetView.cs.meta │ │ ├── Fx_BaseView.cs │ │ ├── Fx_BaseView.cs.meta │ │ ├── Fx_BundleReferenceWindow.cs │ │ ├── Fx_BundleReferenceWindow.cs.meta │ │ ├── Fx_BundleView.cs │ │ ├── Fx_BundleView.cs.meta │ │ ├── Fx_VersionManagerWindow.cs │ │ └── Fx_VersionManagerWindow.cs.meta ├── LICENSE.md ├── LICENSE.md.meta ├── Readme.md ├── Readme.md.meta ├── Runtime.meta ├── Runtime │ ├── AssembleInfo.cs │ ├── AssembleInfo.cs.meta │ ├── AssetPolling.cs │ ├── AssetPolling.cs.meta │ ├── Base.meta │ ├── Base │ │ ├── FxAsyncTask.Global.cs │ │ ├── FxAsyncTask.Global.cs.meta │ │ ├── FxAsyncTask.cs │ │ ├── FxAsyncTask.cs.meta │ │ ├── FxReference.cs │ │ └── FxReference.cs.meta │ ├── Encrypt.meta │ ├── Encrypt │ │ ├── BaseEncrypt.cs │ │ ├── BaseEncrypt.cs.meta │ │ ├── EncryptMode.cs │ │ ├── EncryptMode.cs.meta │ │ ├── FxEncryptOffset.cs │ │ ├── FxEncryptOffset.cs.meta │ │ ├── FxEncryptXor.cs │ │ └── FxEncryptXor.cs.meta │ ├── FDownloadProcess.meta │ ├── FDownloadProcess │ │ ├── Downloader.cs │ │ ├── Downloader.cs.meta │ │ ├── ThreadDownloader.cs │ │ └── ThreadDownloader.cs.meta │ ├── FLoaderProcess.meta │ ├── FLoaderProcess │ │ ├── BundleLoader.cs │ │ ├── BundleLoader.cs.meta │ │ ├── DependBundleLoader.Global.cs │ │ ├── DependBundleLoader.Global.cs.meta │ │ ├── DependBundleLoader.cs │ │ ├── DependBundleLoader.cs.meta │ │ ├── FxAsset.Global.cs │ │ ├── FxAsset.Global.cs.meta │ │ ├── FxAsset.cs │ │ ├── FxAsset.cs.meta │ │ ├── FxRawAsset.Global.cs │ │ ├── FxRawAsset.Global.cs.meta │ │ ├── FxRawAsset.cs │ │ ├── FxRawAsset.cs.meta │ │ ├── FxScene.Global.cs │ │ ├── FxScene.Global.cs.meta │ │ ├── FxScene.cs │ │ └── FxScene.cs.meta │ ├── FTask.meta │ ├── FTask │ │ ├── AsyncFTaskMethodBuilder.cs │ │ ├── AsyncFTaskMethodBuilder.cs.meta │ │ ├── AsyncMethodBuilderAttribute.cs │ │ ├── AsyncMethodBuilderAttribute.cs.meta │ │ ├── FTask.cs │ │ └── FTask.cs.meta │ ├── FUpdateProcess.meta │ ├── FUpdateProcess │ │ ├── CheckDownloadBundle.cs │ │ ├── CheckDownloadBundle.cs.meta │ │ ├── CheckDownloadSize.cs │ │ ├── CheckDownloadSize.cs.meta │ │ ├── CheckLocalManifest.cs │ │ ├── CheckLocalManifest.cs.meta │ │ ├── CheckWWWManifest.cs │ │ └── CheckWWWManifest.cs.meta │ ├── FuXiManager.cs │ ├── FuXiManager.cs.meta │ ├── Fx_Runtime.asmdef │ ├── Fx_Runtime.asmdef.meta │ ├── Helper.meta │ ├── Helper │ │ ├── Crc32Algorithm.cs │ │ ├── Crc32Algorithm.cs.meta │ │ ├── FxDebug.cs │ │ ├── FxDebug.cs.meta │ │ ├── FxHelper.cs │ │ ├── FxHelper.cs.meta │ │ ├── FxUtility.cs │ │ └── FxUtility.cs.meta │ ├── Manifest.meta │ ├── Manifest │ │ ├── FxManifest.cs │ │ ├── FxManifest.cs.meta │ │ ├── FxManifestDriver.cs │ │ └── FxManifestDriver.cs.meta │ ├── RuntimeMode.cs │ └── RuntimeMode.cs.meta ├── package.json └── package.json.meta ├── README.md └── StartUp.md /FuXi/Bridge.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 23edbd3541d7432391a84b8fb3985344 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /FuXi/Bridge/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d95dbc0faca54468b3e52aa9f4418322 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /FuXi/Bridge/Editor/EditorExtension.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | // ReSharper disable once CheckNamespace 3 | namespace UnityEditor 4 | { 5 | public static class EditorExtension 6 | { 7 | public static class EditorStyle 8 | { 9 | public static readonly GUIStyle IconButton = EditorStyles.iconButton; 10 | } 11 | 12 | public static void CallDelay(UnityEditor.EditorApplication.CallbackFunction action, float time) 13 | { 14 | EditorApplication.CallDelayed(action, time); 15 | } 16 | 17 | public static void ClearConsole() 18 | { 19 | LogEntries.Clear(); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /FuXi/Bridge/Editor/EditorExtension.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 377fd7a1015f4842a1dc5d3e24459811 3 | timeCreated: 1650615607 -------------------------------------------------------------------------------- /FuXi/Bridge/Editor/EditorInternalBridge.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Unity.InternalAPIEditorBridge.006", 3 | "references": [], 4 | "includePlatforms": [ 5 | "Editor" 6 | ], 7 | "excludePlatforms": [], 8 | "allowUnsafeCode": false, 9 | "overrideReferences": false, 10 | "precompiledReferences": [], 11 | "autoReferenced": true, 12 | "defineConstraints": [], 13 | "versionDefines": [], 14 | "noEngineReferences": false 15 | } -------------------------------------------------------------------------------- /FuXi/Bridge/Editor/EditorInternalBridge.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3cb8e2b64ae58f7489b88bc90a7703b9 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /FuXi/Bridge/Editor/ProjectBrowserExtension.cs: -------------------------------------------------------------------------------- 1 | using System.Globalization; 2 | using System.Reflection; 3 | using UnityEditor.IMGUI.Controls; 4 | 5 | // ReSharper disable once CheckNamespace 6 | namespace UnityEditor 7 | { 8 | public static class ProjectBrowserExtension 9 | { 10 | public static void RenameSelectAsset() 11 | { 12 | if (Selection.activeObject == null) return; 13 | var browser = ProjectBrowser.s_LastInteractedProjectBrowser; 14 | TreeViewController vc = null; 15 | if (!browser.IsTwoColumns()) 16 | { 17 | var ts = typeof(ProjectBrowser).GetField("m_AssetTree", 18 | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); 19 | vc = ts?.GetValue(browser) as TreeViewController; 20 | if (vc == null) return; 21 | TreeViewItem t1 = vc.data.FindItem(vc.state.lastClickedID); 22 | vc.gui.BeginRename(t1, 0.0f); 23 | } 24 | else 25 | { 26 | browser.ListArea.Frame(Selection.activeInstanceID, true, false); 27 | browser.ListArea.GetRenameOverlay() 28 | .BeginRename(Selection.activeObject.name, Selection.activeInstanceID, 0.0f); 29 | browser.ListArea.repaintCallback?.Invoke(); 30 | } 31 | void RenameCheck() 32 | { 33 | if (!browser.IsTwoColumns()) 34 | { if (vc.state.renameOverlay.IsRenaming()) return; } 35 | else 36 | { if (browser.ListArea.GetRenameOverlay().IsRenaming()) return; } 37 | AssetDatabase.SaveAssets(); 38 | EditorApplication.CallDelayed(() => 39 | { 40 | var method = typeof(ProjectBrowser).GetMethod("ResetViews", BindingFlags.Instance | BindingFlags.NonPublic); 41 | method?.Invoke(browser, BindingFlags.Instance | BindingFlags.NonPublic, null, null, CultureInfo.CurrentCulture); 42 | },0.01); 43 | EditorApplication.update -= RenameCheck; 44 | } 45 | EditorApplication.update += RenameCheck; 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /FuXi/Bridge/Editor/ProjectBrowserExtension.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: adecaf960768478391be11af754f708b 3 | timeCreated: 1649928399 -------------------------------------------------------------------------------- /FuXi/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ### **伏羲** 版本更新日志 2 | 3 | ... ... 4 | 5 | ##V1.1.6 6 | 7 | 1.新增版本更新日志文件 8 | 2.新增自定义包名扩展接口 IPlayerNameDefine, etc: Fx_PlayerName, 其中PlayerNamePriority 设置优先级, 默认选择优先级最高的作为最终包名. 9 | 10 | ##V1.1.7 11 | 12 | 1.补充日志外部控制接口 FX_LOG_CONTROL 13 | 2.修复构建后 编辑器刷新布局错误 14 | 15 | ##V1.1.8 16 | 17 | 1.修复异步加载场景状态更新错误. 18 | 2.移除多余的无效代码. 19 | 20 | ##V1.2.0 21 | 22 | 1.补充运行时使用设置的根路径. 23 | 2.补充断点续传设置参数. 24 | 3.修复分包DLC BUG,分包DLC 不适于独立DLC 单独下载, 适用于全部更新内容. 25 | 26 | ##V1.2.2 27 | 28 | 1.本地 或者 资源服务器没有 version hash 文件时, 视为正常情况. 不影下载响读取服务器 版本 文件. 29 | 2.修复 边玩边下载(异步加载未下载资源) 依赖BUG. 30 | 31 | ##V1.2.5 32 | 33 | 1.修复 Raw File 原生文件 加载路径BUG. 34 | 2.优化 分包 使用 体验. 35 | 3.优化 部分代码. 36 | 37 | ##V1.2.6 38 | 39 | 1.bundle 补充 后处理 接口 参数 diffFiles(版本差异文件列表). -------------------------------------------------------------------------------- /FuXi/CHANGELOG.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 68c79f5f40ceb8a448e4e46a4e709dc5 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /FuXi/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ccf667414652485438da1c02a86fd5a6 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /FuXi/Editor/AssembleInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using UnityEngine; 4 | [assembly: AssemblyVersion("1.1.1.5")] 5 | [assembly: AssemblyIsEditorAssembly] 6 | [assembly: InternalsVisibleTo("FuXi.InternalAPIEditorBridge")] -------------------------------------------------------------------------------- /FuXi/Editor/AssembleInfo.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 24da8f99bb0748afbdd1942897013340 3 | timeCreated: 1649407779 -------------------------------------------------------------------------------- /FuXi/Editor/BuildPipeline.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 65db3846102b41fda75f2fcda38461dd 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /FuXi/Editor/BuildPipeline/BuildBundleProcess.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 907f5a194d32477eaa92ea8143f55e85 3 | timeCreated: 1650001602 -------------------------------------------------------------------------------- /FuXi/Editor/BuildPipeline/BuildPlayerProcess.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d16ca8d9030a489295a27d259b3b0818 3 | timeCreated: 1650536534 -------------------------------------------------------------------------------- /FuXi/Editor/BuildPipeline/IBuild.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | // ReSharper disable once CheckNamespace 3 | namespace FuXi.Editor 4 | { 5 | internal interface IBuild : IDisposable 6 | { 7 | void BeginBuild(); 8 | void EndBuild(); 9 | 10 | void OnAssetValueChanged(); 11 | } 12 | } -------------------------------------------------------------------------------- /FuXi/Editor/BuildPipeline/IBuild.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 339d4607be8441a588c58af9e56f1eb1 3 | timeCreated: 1650873103 -------------------------------------------------------------------------------- /FuXi/Editor/Data.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 75a5721216cb4be3b88c500606106b8e 3 | timeCreated: 1649405912 -------------------------------------------------------------------------------- /FuXi/Editor/Data/Fx_BuildAsset.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using UnityEditor; 4 | using UnityEngine; 5 | 6 | // ReSharper disable once CheckNamespace 7 | namespace FuXi.Editor 8 | { 9 | public enum BundleMode 10 | { 11 | PackByFile, 12 | PackTogether, 13 | PackByDirectory, 14 | PackByTopDirectory, 15 | PackByRaw, 16 | } 17 | [Serializable] 18 | public class Fx_Object 19 | { 20 | public BundleMode bundleMode = BundleMode.PackByFile; 21 | public UnityEngine.Object folder; 22 | } 23 | internal class Fx_BuildAsset : ScriptableObject 24 | { 25 | public int bundleVersion; 26 | public string playerVersion; 27 | public BuildAssetBundleOptions buildAssetBundleOptions = BuildAssetBundleOptions.ChunkBasedCompression; 28 | public List fx_Objects; 29 | } 30 | } -------------------------------------------------------------------------------- /FuXi/Editor/Data/Fx_BuildAsset.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 74b6c21043e1445fbb62f910f69c62d4 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {fileID: 2800000, guid: 0de3dc8ec401d9547b9970fe6e9433e9, type: 3} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /FuXi/Editor/Data/Fx_BuildPackage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | // ReSharper disable once CheckNamespace 6 | namespace FuXi.Editor 7 | { 8 | public class Fx_BuildPackage : ScriptableObject 9 | { 10 | public List PackageObjects; 11 | } 12 | } -------------------------------------------------------------------------------- /FuXi/Editor/Data/Fx_BuildPackage.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fad09892500d426ebd9f5b7828bd24d2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {fileID: 2800000, guid: 4c76924870e4df047a472cc69fa4b065, type: 3} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /FuXi/Editor/Data/Fx_BuildSetting.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | // ReSharper disable once CheckNamespace 5 | namespace FuXi.Editor 6 | { 7 | public enum BuildPlateForm 8 | { 9 | Window, 10 | Android, 11 | IOS, 12 | MacOS, 13 | WebGL, 14 | } 15 | 16 | public class Fx_BuildSetting : ScriptableObject 17 | { 18 | public string BundleRootPath; 19 | public string ExtensionName; 20 | public BuildPlateForm FxPlatform; 21 | public string EncryptType = "None"; 22 | public bool OpenBreakResume; 23 | public bool CopyAllBundle2Player; 24 | public List ExcludeExtensions; 25 | public List BuiltinPackages; 26 | } 27 | } -------------------------------------------------------------------------------- /FuXi/Editor/Data/Fx_BuildSetting.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 47bdac13526f41efa54d03db9847fe79 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {fileID: 2800000, guid: 18af8d12037479b42a450979ecdb2fb2, type: 3} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /FuXi/Editor/Fx_Command.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEditor; 3 | 4 | namespace FuXi.Editor 5 | { 6 | public static class Fx_Command 7 | { 8 | public static void BuildBundle(string platform) 9 | { 10 | try 11 | { 12 | var buildPlatform = Name2BuildTarget(platform); 13 | var buildAsset = BuildHelper.GetBuildAsset(buildPlatform.PlateForm); 14 | new BuildBundleProcess(buildAsset).BeginBuild(); 15 | } 16 | catch (Exception e) 17 | { 18 | FxDebug.ColorError(FX_LOG_CONTROL.Red, "Build bundle failure in platform {0} with error {1}", 19 | platform, e.Message); 20 | } 21 | } 22 | 23 | public static void BuildPlayer(string platform) 24 | { 25 | try 26 | { 27 | var buildPlatform = Name2BuildTarget(platform); 28 | SwitchBuildPlatform(buildPlatform.TargetGroup, buildPlatform.Target); 29 | var buildAsset = BuildHelper.GetBuildAsset(buildPlatform.PlateForm); 30 | new BuildPlayerProcess(buildAsset).BeginBuild(); 31 | } 32 | catch (Exception e) 33 | { 34 | FxDebug.ColorError(FX_LOG_CONTROL.Red, "Build player failure in platform {0} with error {1}", 35 | platform, e.Message); 36 | } 37 | 38 | } 39 | 40 | public static void BuildOneTime(string platform) 41 | { 42 | try 43 | { 44 | var buildPlatform = Name2BuildTarget(platform); 45 | SwitchBuildPlatform(buildPlatform.TargetGroup, buildPlatform.Target); 46 | var buildAsset = BuildHelper.GetBuildAsset(buildPlatform.PlateForm); 47 | new BuildBundleProcess(buildAsset).BeginBuild(); 48 | new BuildPlayerProcess(buildAsset).BeginBuild(); 49 | } 50 | catch (Exception e) 51 | { 52 | FxDebug.ColorError(FX_LOG_CONTROL.Red, "Build failure in platform {0} with error {1}", 53 | platform, e.Message); 54 | } 55 | } 56 | 57 | private static void BuildBundleInternal() 58 | { 59 | BuildBundle("StandaloneWindows64"); 60 | } 61 | 62 | private static void BuildInternal() 63 | { 64 | BuildOneTime(""); 65 | } 66 | 67 | private static void SwitchBuildPlatform(BuildTargetGroup targetGroup, BuildTarget target) 68 | { 69 | var switchRes = EditorUserBuildSettings.SwitchActiveBuildTarget(targetGroup, target); 70 | if (!switchRes) 71 | throw new Exception("Switch platform failure!"); 72 | 73 | } 74 | 75 | private static BuildTargetInfo Name2BuildTarget(string platform) 76 | { 77 | BuildTargetInfo info = new BuildTargetInfo(); 78 | switch (platform) 79 | { 80 | case "Android": 81 | info.Target = BuildTarget.Android; 82 | info.TargetGroup = BuildTargetGroup.Android; 83 | info.PlateForm = BuildPlateForm.Android; 84 | break; 85 | case "StandaloneWindows": 86 | info.Target = BuildTarget.StandaloneWindows; 87 | info.TargetGroup = BuildTargetGroup.Standalone; 88 | info.PlateForm = BuildPlateForm.Window; 89 | break; 90 | case "StandaloneWindows64": 91 | info.Target = BuildTarget.StandaloneWindows64; 92 | info.TargetGroup = BuildTargetGroup.Standalone; 93 | info.PlateForm = BuildPlateForm.Window; 94 | break; 95 | case "IOS": 96 | info.Target = BuildTarget.iOS; 97 | info.TargetGroup = BuildTargetGroup.iOS; 98 | info.PlateForm = BuildPlateForm.IOS; 99 | break; 100 | case "StandaloneOSX": 101 | info.Target = BuildTarget.StandaloneOSX; 102 | info.TargetGroup = BuildTargetGroup.iOS; 103 | info.PlateForm = BuildPlateForm.MacOS; 104 | break; 105 | case "WebGL": 106 | info.Target = BuildTarget.WebGL; 107 | info.TargetGroup = BuildTargetGroup.WebGL; 108 | info.PlateForm = BuildPlateForm.WebGL; 109 | break; 110 | default: 111 | throw new Exception($"Platform {platform} is invalid!"); 112 | } 113 | return info; 114 | } 115 | 116 | private struct BuildTargetInfo 117 | { 118 | internal BuildTarget Target; 119 | internal BuildTargetGroup TargetGroup; 120 | internal BuildPlateForm PlateForm; 121 | } 122 | } 123 | } -------------------------------------------------------------------------------- /FuXi/Editor/Fx_Command.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 10653d47860045978fa4e47f2c0b6d80 3 | timeCreated: 1655718225 -------------------------------------------------------------------------------- /FuXi/Editor/Fx_CreateMenu.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | using UnityEngine; 3 | 4 | namespace FuXi.Editor 5 | { 6 | internal static class Fx_CreateMenu 7 | { 8 | [MenuItem("Assets/Create/FuXi/FuXi Asset", false, 106)] 9 | private static void CreateFuXiAsset() 10 | { 11 | ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, 12 | ScriptableObject.CreateInstance(), Fx_EditorConfigs.DefaultAssetName, Fx_Style.Fx_Asset, null); 13 | } 14 | 15 | [MenuItem("Assets/Create/FuXi/Add Package", false, 121)] 16 | private static void AddPackage() 17 | { 18 | if (Selection.activeObject.GetType() != typeof(Fx_BuildAsset)) 19 | { 20 | throw new System.ComponentModel.WarningException("can't add fuXi package to nonFuXiAsset!"); 21 | } 22 | var resourceFile = AssetDatabase.GetAssetPath(Selection.activeObject); 23 | ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, 24 | ScriptableObject.CreateInstance(), Fx_EditorConfigs.AdditionPackageName, Fx_Style.Fx_AssetPackage, resourceFile); 25 | } 26 | 27 | [MenuItem("Assets/Create/FuXi/Remove Package", false, 121)] 28 | private static void RemovePackage() 29 | { 30 | var buildPackage = Selection.activeObject as Fx_BuildPackage; 31 | if (buildPackage == null) 32 | { 33 | throw new System.ComponentModel.WarningException($"can't remove {Selection.activeObject.GetType()} from fuXi asset!"); 34 | } 35 | foreach (var o in Selection.objects) 36 | { 37 | AssetDatabase.RemoveObjectFromAsset(o); 38 | } 39 | AssetDatabase.SaveAssets(); 40 | } 41 | 42 | [MenuItem("Assets/Create/FuXi/Rename Package", false, 201)] 43 | private static void RenamePackage() 44 | { 45 | if (Selection.activeObject.GetType() != typeof(Fx_BuildPackage)) return; 46 | ProjectBrowserExtension.RenameSelectAsset(); 47 | } 48 | 49 | [UnityEditor.Callbacks.OnOpenAsset(0)] 50 | private static bool OnMapAssetOpened(int instanceId, int line) 51 | { 52 | var path = AssetDatabase.GetAssetPath(instanceId); 53 | var instance = AssetDatabase.LoadAssetAtPath(path); 54 | if (instance == null) return false; 55 | EditorWindow.GetWindow(); 56 | return true; 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /FuXi/Editor/Fx_CreateMenu.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 14e29eb5802e43f580a363f7b8193fd7 3 | timeCreated: 1649384213 -------------------------------------------------------------------------------- /FuXi/Editor/Fx_Editor.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "FuXi.Editor", 3 | "rootNamespace": "", 4 | "references": [ 5 | "GUID:3cb8e2b64ae58f7489b88bc90a7703b9", 6 | "GUID:1c64a098c7bf73e4ba2651fb3807a7f4" 7 | ], 8 | "includePlatforms": [ 9 | "Editor" 10 | ], 11 | "excludePlatforms": [], 12 | "allowUnsafeCode": false, 13 | "overrideReferences": false, 14 | "precompiledReferences": [], 15 | "autoReferenced": true, 16 | "defineConstraints": [], 17 | "versionDefines": [], 18 | "noEngineReferences": false 19 | } -------------------------------------------------------------------------------- /FuXi/Editor/Fx_Editor.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4747d22a2b65fba4c98b2588acf70724 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /FuXi/Editor/Fx_EditorConfigs.cs: -------------------------------------------------------------------------------- 1 | namespace FuXi.Editor 2 | { 3 | public static class Fx_EditorConfigs 4 | { 5 | public static readonly string DefaultAssetName = "FuXiAsset.asset"; 6 | public static readonly string FirstPackageName = "Builtin"; 7 | public static readonly string AdditionPackageName = "Addition"; 8 | public static readonly string SettingName = "Settings"; 9 | 10 | public static readonly string AboutURL = "https://github.com/mistletoeKANO/fuxi"; 11 | } 12 | } -------------------------------------------------------------------------------- /FuXi/Editor/Fx_EditorConfigs.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9f0798658e494889b918cf9a886b4c4a 3 | timeCreated: 1649388406 -------------------------------------------------------------------------------- /FuXi/Editor/Fx_InitializeBeforeSceneLoad.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEditor; 3 | using UnityEngine; 4 | 5 | namespace FuXi.Editor 6 | { 7 | public static class Fx_InitializeBeforeSceneLoad 8 | { 9 | [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] 10 | private static void InitFxAssetBeforeSceneLoad() 11 | { 12 | FxScene.FxSceneCreate = FxEditorScene.CreateEditorScene; 13 | FxAsset.FxAssetCreate = FxEditorAsset.CreateEditorAsset; 14 | FxRawAsset.FxRawAssetCreate = FxEditorRawAsset.CreateEditorRawAsset; 15 | FuXiManager.ParseManifestCallback = CreateManifest; 16 | } 17 | 18 | private static FxManifest CreateManifest() 19 | { 20 | var manifest = new FxManifest(); 21 | BuildPlateForm buildPlateForm = RunPlatform2BuildPlatform(); 22 | Fx_BuildAsset buildAsset = BuildHelper.GetBuildAsset(buildPlateForm); 23 | 24 | if (buildAsset == null) 25 | { 26 | FxDebug.LogError("build asset is not found for this platform!"); 27 | return null; 28 | } 29 | Fx_BuildSetting buildSetting = 30 | UnityEditor.AssetDatabase.LoadAssetAtPath(AssetDatabase.GetAssetPath(buildAsset)); 31 | manifest.RootPath = buildSetting.BundleRootPath; 32 | manifest.EncryptType = buildSetting.EncryptType; 33 | 34 | List assetManifests = new List(); 35 | 36 | foreach (var folder in buildAsset.fx_Objects) 37 | { 38 | if (folder.folder == null) 39 | { 40 | FxDebug.LogError($"{buildAsset.name} asset is null or missing!"); 41 | continue; 42 | } 43 | var folderPath = AssetDatabase.GetAssetPath(folder.folder); 44 | if (AssetDatabase.IsValidFolder(folderPath)) 45 | { 46 | var assets = AssetDatabase.FindAssets("*", new[] {folderPath}); 47 | foreach (var asset in assets) 48 | { 49 | var p = AssetDatabase.GUIDToAssetPath(asset); 50 | if (AssetDatabase.IsValidFolder(p)) continue; 51 | assetManifests.Add(new AssetManifest{Path = p, IsRawFile = folder.bundleMode == BundleMode.PackByRaw}); 52 | } 53 | } 54 | else 55 | { 56 | assetManifests.Add(new AssetManifest {Path = folderPath}); 57 | } 58 | } 59 | 60 | foreach (var asManifest in assetManifests) 61 | { 62 | if (manifest.Path2AssetManifest.ContainsKey(asManifest.Path)) continue; 63 | manifest.Path2AssetManifest.Add(asManifest.Path, asManifest); 64 | } 65 | FxDebug.ColorLog(FX_LOG_CONTROL.Green, "Load editor manifest {0}.", buildAsset.name); 66 | return manifest; 67 | } 68 | 69 | private static BuildPlateForm RunPlatform2BuildPlatform() 70 | { 71 | switch (Application.platform) 72 | { 73 | case RuntimePlatform.Android: 74 | return BuildPlateForm.Android; 75 | case RuntimePlatform.WindowsEditor: 76 | case RuntimePlatform.WindowsPlayer: 77 | return BuildPlateForm.Window; 78 | case RuntimePlatform.IPhonePlayer: 79 | return BuildPlateForm.IOS; 80 | case RuntimePlatform.OSXEditor: 81 | case RuntimePlatform.OSXPlayer: 82 | return BuildPlateForm.MacOS; 83 | case RuntimePlatform.WebGLPlayer: 84 | return BuildPlateForm.WebGL; 85 | default: 86 | return BuildPlateForm.Window; 87 | } 88 | } 89 | } 90 | } -------------------------------------------------------------------------------- /FuXi/Editor/Fx_InitializeBeforeSceneLoad.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8bf182a033ab43db91e3599364ba92af 3 | timeCreated: 1653387687 -------------------------------------------------------------------------------- /FuXi/Editor/Fx_Style.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | using UnityEngine; 3 | 4 | namespace FuXi.Editor 5 | { 6 | public static class Fx_Style 7 | { 8 | internal static readonly Texture2D Fx_Asset = Resources.Load("Gizmos/Fx_Asset"); 9 | internal static readonly Texture2D Fx_About = Resources.Load("Gizmos/Fx_About"); 10 | internal static readonly Texture2D Fx_PathMenu = Resources.Load("Gizmos/Fx_PathMenu"); 11 | internal static readonly Texture2D Fx_AssetBlack = Resources.Load("Gizmos/Fx_Asset Black"); 12 | internal static readonly Texture2D Fx_AssetPackage = Resources.Load("Gizmos/Fx_AssetPackage"); 13 | 14 | internal static readonly GUIContent RefWindowTitle = new GUIContent("引用分析", Resources.Load("Gizmos/Fx_Asset Black")); 15 | internal static readonly GUIContent VerWindowTitle = new GUIContent("版本预览", Resources.Load("Gizmos/Fx_Asset Black")); 16 | internal static readonly GUIContent PrefabIcon = EditorGUIUtility.IconContent("d_Prefab Icon"); 17 | internal static readonly GUIContent BundleIcon = EditorGUIUtility.IconContent("d_ScriptableObject Icon"); 18 | internal static readonly GUIContent PinButton = EditorGUIUtility.IconContent("d__Help@2x"); 19 | 20 | internal static readonly GUIStyle ByteStyle = new GUIStyle 21 | {alignment = TextAnchor.MiddleRight, normal = {textColor = new Color(1f, 0.42f, 0.1f)}}; 22 | 23 | internal static readonly GUIStyle FooterLabelInfo = new GUIStyle 24 | { 25 | margin = new RectOffset(18,0,0,0), 26 | normal = new GUIStyleState{textColor = Color.gray} 27 | }; 28 | 29 | internal static readonly GUIStyle LabelTitleCyan; 30 | internal static readonly GUIStyle LabelInfo; 31 | internal static readonly GUIStyle LabelInfoMiddle; 32 | internal static readonly GUIStyle LabelBG; 33 | internal static readonly GUIStyle Space; 34 | 35 | internal static readonly string CName_BF_Toolbar = "bf-toolbar"; 36 | internal static readonly string CName_BF_Toolbar_Enum = "bf-toolbar-enum"; 37 | internal static readonly string CName_BF_MainView_Header = "bf-main-view-header"; 38 | internal static readonly string CName_BF_MainView = "bf-main-view"; 39 | internal static readonly string CName_BF_MainView_BG = "bf-main-view-bg"; 40 | internal static readonly string CName_BF_MainView_ScrollView = "bf-main-view-scroll-view"; 41 | internal static readonly string CName_BF_Footer = "bf-footer"; 42 | internal static readonly string CName_BF_Footer_Header = "bf-footer-header"; 43 | internal static readonly string CName_BF_Footer_Label = "bf-footer-label"; 44 | internal static readonly string CName_BF_Footer_View = "bf-footer-view"; 45 | 46 | internal static readonly string CName_VM_Toolbar = "vm-toolbar"; 47 | internal static readonly string CName_VM_Toolbar_DropMenu = "vm-toolbar-drop-menu"; 48 | internal static readonly string CName_VM_MainView = "vm-main-view"; 49 | internal static readonly string CName_VM_MainView_BG = "vm-main-view-bg"; 50 | internal static readonly string CName_VM_MainView_Info = "vm-main-view-info"; 51 | internal static readonly string CName_VM_MainView_BundleList = "vm-main-view-bundle-list"; 52 | internal static readonly string CName_VM_Footer = "vm-footer"; 53 | 54 | internal static readonly Color C_ColumnDark = new Color(0.16f, 0.16f, 0.16f, 0.6f); 55 | internal static readonly Color C_ColumnLight = new Color(0.25f, 0.25f, 0.25f, 0.6f); 56 | 57 | static Fx_Style() 58 | { 59 | Space = new GUIStyle() 60 | { 61 | stretchHeight = false, 62 | normal = new GUIStyleState(){background = Resources.Load("Images/Label_Bottom_Line")} 63 | }; 64 | LabelTitleCyan = new GUIStyle 65 | { 66 | alignment = TextAnchor.MiddleCenter, 67 | fontSize = 16, 68 | fontStyle = FontStyle.Bold, 69 | clipping = TextClipping.Clip, 70 | normal = new GUIStyleState{textColor = new Color(0.17f, 0.52f, 0.62f, 0.85f)}, 71 | }; 72 | LabelInfo = new GUIStyle 73 | { 74 | alignment = TextAnchor.MiddleLeft, 75 | fontSize = 12, 76 | clipping = TextClipping.Clip, 77 | margin = new RectOffset(10, 1, 1, 5), 78 | normal = {textColor = new Color(0.58f, 0.58f, 0.58f, 0.85f)}, 79 | }; 80 | LabelInfoMiddle = new GUIStyle(LabelInfo) 81 | { 82 | alignment = TextAnchor.MiddleCenter, 83 | margin = new RectOffset(0,0,0,0) 84 | }; 85 | LabelBG = new GUIStyle(Space) 86 | { 87 | alignment = TextAnchor.MiddleLeft, 88 | fontSize = 12, 89 | stretchHeight = false, 90 | padding = new RectOffset(10,2,2,2), 91 | normal = {textColor = new Color(0.58f, 0.58f, 0.58f, 0.85f)}, 92 | }; 93 | } 94 | } 95 | } -------------------------------------------------------------------------------- /FuXi/Editor/Fx_Style.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 49b9349ece0c40318bdf69667419a3a0 3 | timeCreated: 1649402359 -------------------------------------------------------------------------------- /FuXi/Editor/Helper.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6e3538f60ad6494982319086db83210e 3 | timeCreated: 1649411367 -------------------------------------------------------------------------------- /FuXi/Editor/Helper/BuildHelper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e4bd34f79b8047bb9ad61001dbbfd9e8 3 | timeCreated: 1650003363 -------------------------------------------------------------------------------- /FuXi/Editor/Helper/DoCreateFuXiBuildAsset.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | 3 | // ReSharper disable once CheckNamespace 4 | namespace FuXi.Editor 5 | { 6 | public class DoCreateFuXiBuildAsset : UnityEditor.ProjectWindowCallback.EndNameEditAction 7 | { 8 | public override void Action(int instanceId, string pathName, string resourceFile) 9 | { 10 | var mainAsset = UnityEngine.ScriptableObject.CreateInstance(); 11 | AssetDatabase.CreateAsset(mainAsset, pathName); 12 | 13 | var settings = UnityEngine.ScriptableObject.CreateInstance(); 14 | { 15 | settings.name = Fx_EditorConfigs.SettingName; 16 | } 17 | var firstPackage = UnityEngine.ScriptableObject.CreateInstance(); 18 | { 19 | firstPackage.name = Fx_EditorConfigs.FirstPackageName; 20 | } 21 | AssetDatabase.AddObjectToAsset(settings, mainAsset); 22 | AssetDatabase.AddObjectToAsset(firstPackage, mainAsset); 23 | AssetDatabase.SaveAssets(); 24 | ProjectWindowUtil.ShowCreatedAsset((UnityEngine.Object) mainAsset); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /FuXi/Editor/Helper/DoCreateFuXiBuildAsset.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 68ac5f8ca5874fbbafb330f46fdd097e 3 | timeCreated: 1649397603 -------------------------------------------------------------------------------- /FuXi/Editor/Helper/DoCreateFuXiBuildPackage.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEditor; 3 | 4 | // ReSharper disable once CheckNamespace 5 | namespace FuXi.Editor 6 | { 7 | public class DoCreateFuXiBuildPackage : UnityEditor.ProjectWindowCallback.EndNameEditAction 8 | { 9 | public override void Action(int instanceId, string pathName, string resourceFile) 10 | { 11 | var fileName = System.IO.Path.GetFileNameWithoutExtension(pathName); 12 | var mainAsset = AssetDatabase.LoadAssetAtPath(resourceFile); 13 | var addPackage = UnityEngine.ScriptableObject.CreateInstance(); 14 | { 15 | addPackage.name = this.GetUniquePackageName(resourceFile, fileName); 16 | } 17 | AssetDatabase.AddObjectToAsset(addPackage, mainAsset); 18 | AssetDatabase.SaveAssets(); 19 | } 20 | 21 | private string GetUniquePackageName(string resourceFile, string curName) 22 | { 23 | var existPackages = AssetDatabase.LoadAllAssetsAtPath(resourceFile); 24 | List names = new List(); 25 | foreach (var p in existPackages) 26 | { 27 | if (p is Fx_BuildPackage package) { names.Add(package.name); } 28 | } 29 | int index = 0; 30 | string resName = curName; 31 | while (names.Contains(resName)) 32 | { 33 | resName = $"{curName} {index}"; 34 | index ++; 35 | } 36 | return resName; 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /FuXi/Editor/Helper/DoCreateFuXiBuildPackage.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 88ed169ffff94f66a99c8d93359b18be 3 | timeCreated: 1649409896 -------------------------------------------------------------------------------- /FuXi/Editor/Helper/Fx_PlayerName.cs: -------------------------------------------------------------------------------- 1 | namespace FuXi.Editor 2 | { 3 | [PlayerNamePriority(0)] 4 | public class Fx_PlayerName : IPlayerNameDefine 5 | { 6 | public string GetPlayerName(string version) 7 | { 8 | var targetName = $"/fx-v{version}-{System.DateTime.Now:yyyyMMdd-HHmmss}"; 9 | switch (UnityEditor.EditorUserBuildSettings.activeBuildTarget) 10 | { 11 | case UnityEditor.BuildTarget.Android: 12 | return targetName + ".apk"; 13 | case UnityEditor.BuildTarget.StandaloneWindows: 14 | case UnityEditor.BuildTarget.StandaloneWindows64: 15 | return targetName + ".exe"; 16 | case UnityEditor.BuildTarget.StandaloneOSX: 17 | return targetName + ".app"; 18 | default: 19 | return targetName; 20 | } 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /FuXi/Editor/Helper/Fx_PlayerName.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c429104a31144c2099281eabf20a512b 3 | timeCreated: 1660541692 -------------------------------------------------------------------------------- /FuXi/Editor/Helper/IBuildPreprocess.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FuXi.Editor 4 | { 5 | /// 6 | /// 构建Bundle 预处理 后处理 操作 接口 7 | /// 8 | public interface IBuildBundlePreprocess 9 | { 10 | /// 11 | /// 构建Bundle 包 预处理 12 | /// 13 | void BuildBundlePre(); 14 | /// 15 | /// 构建Bundle 包 后处理 16 | /// 17 | void BuildBundlePost(List diffFiles); 18 | } 19 | /// 20 | /// 构建 安装包 预处理 后处理 操作 接口 21 | /// 22 | public interface IBuildPlayerPreprocess 23 | { 24 | /// 25 | /// 构建Bundle 包 预处理 26 | /// 27 | void BuildPlayerPre(); 28 | /// 29 | /// 构建Bundle 包 后处理 30 | /// 31 | void BuildPlayerPost(); 32 | } 33 | } -------------------------------------------------------------------------------- /FuXi/Editor/Helper/IBuildPreprocess.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 991c9d11c48905149b9d1c22baf48293 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /FuXi/Editor/Helper/IPlayerNameDefine.cs: -------------------------------------------------------------------------------- 1 | namespace FuXi.Editor 2 | { 3 | public class PlayerNamePriorityAttribute : System.Attribute 4 | { 5 | public int priority; 6 | public PlayerNamePriorityAttribute(int priority) { this.priority = priority; } 7 | } 8 | 9 | /// 10 | /// 自定义包名 11 | /// 12 | public interface IPlayerNameDefine 13 | { 14 | /// 15 | /// 获取 自定义 包名 16 | /// 17 | /// unity 设置 安装包 版本 18 | /// 19 | public string GetPlayerName(string version); 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /FuXi/Editor/Helper/IPlayerNameDefine.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8d4c1b80065d48d2ad55dd010a1e8cf2 3 | timeCreated: 1660541358 -------------------------------------------------------------------------------- /FuXi/Editor/Helper/ProcessingHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace FuXi.Editor 5 | { 6 | internal static class ProcessingHelper 7 | { 8 | /// 9 | /// 获取所有Bundle 预处理指令 10 | /// 11 | /// 12 | internal static List AcquireAllBundlePreProcess() 13 | { 14 | return AcquirePreProcessInternal(); 15 | } 16 | 17 | /// 18 | /// 获取所有Player 预处理指令 19 | /// 20 | /// 21 | internal static List AcquireAllPlayerPreProcess() 22 | { 23 | return AcquirePreProcessInternal(); 24 | } 25 | 26 | private static List AcquirePreProcessInternal() 27 | { 28 | List preprocesses = new List(); 29 | var typeBase = typeof(T); 30 | var assembles = AppDomain.CurrentDomain.GetAssemblies(); 31 | foreach (var assembly in assembles) 32 | { 33 | if (BuildHelper.CheckIgnore(assembly.GetName().Name)) continue; 34 | 35 | System.Type[] types = assembly.GetTypes(); 36 | foreach (System.Type type in types) 37 | { 38 | if (type.IsClass && !type.IsAbstract && typeBase.IsAssignableFrom(type)) 39 | { 40 | var ins = (T) Activator.CreateInstance(type); 41 | preprocesses.Add(ins); 42 | } 43 | } 44 | } 45 | return preprocesses; 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /FuXi/Editor/Helper/ProcessingHelper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bbc398c597154cc69a680daed45b17ce 3 | timeCreated: 1655348927 -------------------------------------------------------------------------------- /FuXi/Editor/Inspector.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c61259e99642458ab5eaa19ad0a514b6 3 | timeCreated: 1649405965 -------------------------------------------------------------------------------- /FuXi/Editor/Inspector/Fx_BuildAssetInspector.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cd923e3efaf045deb86ac15cfe3ceb13 3 | timeCreated: 1649406023 -------------------------------------------------------------------------------- /FuXi/Editor/Inspector/Fx_BuildPackageInspector.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | using UnityEngine; 3 | 4 | // ReSharper disable once CheckNamespace 5 | namespace FuXi.Editor 6 | { 7 | [CustomEditor(typeof(Fx_BuildPackage), true)] 8 | [CanEditMultipleObjects] 9 | public class Fx_BuildPackageInspector : UnityEditor.Editor 10 | { 11 | static class Style 12 | { 13 | public static readonly GUIContent PackageObjects = EditorGUIUtility.TrTextContent("分包资产"); 14 | } 15 | 16 | SerializedProperty m_PackageObjects; 17 | 18 | private void OnEnable() 19 | { 20 | this.m_PackageObjects = serializedObject.FindProperty("PackageObjects"); 21 | } 22 | 23 | public override bool UseDefaultMargins() { return false; } 24 | 25 | public override void OnInspectorGUI() 26 | { 27 | serializedObject.Update(); 28 | EditorGUILayout.Space(2); 29 | EditorGUILayout.PropertyField(this.m_PackageObjects, Style.PackageObjects); 30 | serializedObject.ApplyModifiedProperties(); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /FuXi/Editor/Inspector/Fx_BuildPackageInspector.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c5b7277316a64b968922efaa337abdd9 3 | timeCreated: 1649406218 -------------------------------------------------------------------------------- /FuXi/Editor/Inspector/Fx_BuildSettingInspector.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | using UnityEngine; 3 | 4 | // ReSharper disable once CheckNamespace 5 | namespace FuXi.Editor 6 | { 7 | [CustomEditor(typeof(Fx_BuildSetting), true)] 8 | public class Fx_BuildSettingInspector : UnityEditor.Editor 9 | { 10 | static class Style 11 | { 12 | public static readonly GUIContent BundleRootPath = EditorGUIUtility.TrTextContent("资源根路径","AssetBundle 资源 根路径"); 13 | public static readonly GUIContent ExtensionName = EditorGUIUtility.TrTextContent("AB包拓展名"); 14 | public static readonly GUIContent FxPlatform = EditorGUIUtility.TrTextContent("配置所属平台"); 15 | public static readonly GUIContent EncryptType = EditorGUIUtility.TrTextContent("加密类型"); 16 | public static readonly GUIContent OpenBreakResume = EditorGUIUtility.TrTextContent("开启断点续传"); 17 | public static readonly GUIContent CopyAllBundle2Player = EditorGUIUtility.TrTextContent("拷贝所有Bundle到安装包"); 18 | public static readonly GUIContent ExcludeExtensions = EditorGUIUtility.TrTextContent("忽略打包文件后缀"); 19 | public static readonly GUIContent BuiltinPackages = EditorGUIUtility.TrTextContent("首包包含的分包"); 20 | } 21 | 22 | SerializedProperty m_BundleRootPath; 23 | SerializedProperty m_ExtensionName; 24 | SerializedProperty m_FxPlatform; 25 | SerializedProperty m_EncryptType; 26 | SerializedProperty m_OpenBreakResume; 27 | SerializedProperty m_CopyAllBundle2Player; 28 | SerializedProperty m_ExcludeExtensions; 29 | SerializedProperty m_BuiltinPackages; 30 | 31 | private string[] encryptOptions; 32 | private int encryptSelectIndex = 0; 33 | private bool IsCopyAllValid = true; 34 | 35 | private void OnEnable() 36 | { 37 | this.m_BundleRootPath = serializedObject.FindProperty("BundleRootPath"); 38 | this.m_ExtensionName = serializedObject.FindProperty("ExtensionName"); 39 | this.m_FxPlatform = serializedObject.FindProperty("FxPlatform"); 40 | this.m_EncryptType = serializedObject.FindProperty("EncryptType"); 41 | this.m_OpenBreakResume = serializedObject.FindProperty("OpenBreakResume"); 42 | this.m_CopyAllBundle2Player = serializedObject.FindProperty("CopyAllBundle2Player"); 43 | this.m_ExcludeExtensions = serializedObject.FindProperty("ExcludeExtensions"); 44 | this.m_BuiltinPackages = serializedObject.FindProperty("BuiltinPackages"); 45 | 46 | this.InitEncrypt(); 47 | } 48 | 49 | private void InitEncrypt() 50 | { 51 | this.encryptOptions = BuildHelper.GetEncryptOptions(); 52 | for (int i = 0; i < this.encryptOptions.Length; i++) 53 | { 54 | if (this.encryptOptions[i] == this.m_EncryptType.stringValue) 55 | { 56 | this.encryptSelectIndex = i; 57 | } 58 | } 59 | this.IsCopyAllValid = this.CheckCopyAllValidate(); 60 | } 61 | public override bool UseDefaultMargins() { return false; } 62 | 63 | public override void OnInspectorGUI() 64 | { 65 | serializedObject.Update(); 66 | EditorGUILayout.Space(2); 67 | EditorGUILayout.PropertyField(this.m_BundleRootPath, Style.BundleRootPath); 68 | EditorGUILayout.PropertyField(this.m_ExtensionName, Style.ExtensionName); 69 | EditorGUILayout.PropertyField(this.m_FxPlatform, Style.FxPlatform); 70 | 71 | EditorGUI.BeginChangeCheck(); 72 | int selectIndex = EditorGUILayout.Popup(Style.EncryptType, this.encryptSelectIndex, this.encryptOptions); 73 | if (selectIndex != this.encryptSelectIndex) 74 | { 75 | this.m_EncryptType.stringValue = this.encryptOptions[selectIndex]; 76 | this.encryptSelectIndex = selectIndex; 77 | } 78 | EditorGUILayout.PropertyField(this.m_OpenBreakResume, Style.OpenBreakResume); 79 | EditorGUILayout.PropertyField(this.m_CopyAllBundle2Player, Style.CopyAllBundle2Player); 80 | if (EditorGUI.EndChangeCheck()) 81 | { 82 | this.IsCopyAllValid = this.CheckCopyAllValidate(); 83 | } 84 | 85 | if (!this.IsCopyAllValid) 86 | { 87 | EditorGUILayout.HelpBox("仅未加密或者OFFSET加密支持全拷贝! 详情查看相关说明!", MessageType.Warning); 88 | } 89 | 90 | EditorGUILayout.PropertyField(this.m_ExcludeExtensions, Style.ExcludeExtensions); 91 | EditorGUILayout.PropertyField(this.m_BuiltinPackages, Style.BuiltinPackages); 92 | 93 | this.OnFooterGUI(); 94 | serializedObject.ApplyModifiedProperties(); 95 | } 96 | 97 | private bool CheckCopyAllValidate() 98 | { 99 | if (this.encryptSelectIndex == 0) 100 | return true; 101 | var encryptFullName = this.encryptOptions[encryptSelectIndex]; 102 | var encryptType = BuildHelper.LoadEncryptObject(encryptFullName); 103 | if (encryptType == null) 104 | return true; 105 | if (this.m_CopyAllBundle2Player.boolValue) 106 | return encryptType.EncryptMode == EncryptMode.OFFSET; 107 | return true; 108 | } 109 | 110 | private void OnFooterGUI() 111 | { 112 | GUILayout.BeginHorizontal(); 113 | if (GUILayout.Button("Copy Bundle", GUILayout.Height(30))) 114 | { 115 | if (EditorUtility.DisplayDialog("Copy Bundle", "Are you sure Copy bundle to StreamingAssets?", 116 | "YES", "NO")) 117 | { 118 | EditorExtension.CallDelay(this.DelayCopyBundle, 0.1f); 119 | return; 120 | } 121 | } 122 | if (GUILayout.Button("Clear Bundle", GUILayout.Height(30))) 123 | { 124 | if (EditorUtility.DisplayDialog("Clear Bundle", "Are you sure Clear bundle from StreamingAssets?", 125 | "YES", "NO")) 126 | { 127 | EditorExtension.CallDelay(this.DelayClearBundle, 0.1f); 128 | return; 129 | } 130 | } 131 | 132 | GUILayout.EndHorizontal(); 133 | } 134 | 135 | private void DelayCopyBundle() 136 | { 137 | var fxAsset = AssetDatabase.LoadAssetAtPath(AssetDatabase.GetAssetPath(this.target)); 138 | new BuildPlayerProcess(fxAsset).BeginCopyBundle(); 139 | } 140 | 141 | private void DelayClearBundle() 142 | { 143 | new BuildPlayerProcess().BeginClearStreamingAssets(); 144 | } 145 | } 146 | } -------------------------------------------------------------------------------- /FuXi/Editor/Inspector/Fx_BuildSettingInspector.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a0d518859ae042669bc33d6ae8da4432 3 | timeCreated: 1649406161 -------------------------------------------------------------------------------- /FuXi/Editor/Resources.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a7c92c28c65246a439b53e03825e6226 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /FuXi/Editor/Resources/Fx_ReferenceView.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mistletoeKANO/fuxi/a8e670cf593b7854fe3b5678c0e74f62f29a432b/FuXi/Editor/Resources/Fx_ReferenceView.jpg -------------------------------------------------------------------------------- /FuXi/Editor/Resources/Fx_ReferenceView.jpg.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e073fbff725f3cc4383bcd6bbd1e4032 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | vTOnly: 0 27 | grayScaleToAlpha: 0 28 | generateCubemap: 6 29 | cubemapConvolution: 0 30 | seamlessCubemap: 0 31 | textureFormat: 1 32 | maxTextureSize: 2048 33 | textureSettings: 34 | serializedVersion: 2 35 | filterMode: -1 36 | aniso: -1 37 | mipBias: -100 38 | wrapU: -1 39 | wrapV: -1 40 | wrapW: -1 41 | nPOTScale: 1 42 | lightmap: 0 43 | compressionQuality: 50 44 | spriteMode: 0 45 | spriteExtrude: 1 46 | spriteMeshType: 1 47 | alignment: 0 48 | spritePivot: {x: 0.5, y: 0.5} 49 | spritePixelsToUnits: 100 50 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 51 | spriteGenerateFallbackPhysicsShape: 1 52 | alphaUsage: 1 53 | alphaIsTransparency: 0 54 | spriteTessellationDetail: -1 55 | textureType: 0 56 | textureShape: 1 57 | singleChannelComponent: 0 58 | flipbookRows: 1 59 | flipbookColumns: 1 60 | maxTextureSizeSet: 0 61 | compressionQualitySet: 0 62 | textureFormatSet: 0 63 | ignorePngGamma: 0 64 | applyGammaDecoding: 0 65 | platformSettings: 66 | - serializedVersion: 3 67 | buildTarget: DefaultTexturePlatform 68 | maxTextureSize: 2048 69 | resizeAlgorithm: 0 70 | textureFormat: -1 71 | textureCompression: 1 72 | compressionQuality: 50 73 | crunchedCompression: 0 74 | allowsAlphaSplitting: 0 75 | overridden: 0 76 | androidETC2FallbackOverride: 0 77 | forceMaximumCompressionQuality_BC6H_BC7: 0 78 | spriteSheet: 79 | serializedVersion: 2 80 | sprites: [] 81 | outline: [] 82 | physicsShape: [] 83 | bones: [] 84 | spriteID: 85 | internalID: 0 86 | vertices: [] 87 | indices: 88 | edges: [] 89 | weights: [] 90 | secondaryTextures: [] 91 | spritePackingTag: 92 | pSDRemoveMatte: 0 93 | pSDShowRemoveMatteOption: 0 94 | userData: 95 | assetBundleName: 96 | assetBundleVariant: 97 | -------------------------------------------------------------------------------- /FuXi/Editor/Resources/Gizmos.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f990a8515670c1e458866fa750877b11 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /FuXi/Editor/Resources/Gizmos/Fx_About.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mistletoeKANO/fuxi/a8e670cf593b7854fe3b5678c0e74f62f29a432b/FuXi/Editor/Resources/Gizmos/Fx_About.png -------------------------------------------------------------------------------- /FuXi/Editor/Resources/Gizmos/Fx_About.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c20c58a4ffd4c334d913532abd0402fa 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | vTOnly: 0 27 | grayScaleToAlpha: 0 28 | generateCubemap: 6 29 | cubemapConvolution: 0 30 | seamlessCubemap: 0 31 | textureFormat: 1 32 | maxTextureSize: 2048 33 | textureSettings: 34 | serializedVersion: 2 35 | filterMode: -1 36 | aniso: 1 37 | mipBias: -100 38 | wrapU: 1 39 | wrapV: 1 40 | wrapW: -1 41 | nPOTScale: 0 42 | lightmap: 0 43 | compressionQuality: 50 44 | spriteMode: 0 45 | spriteExtrude: 1 46 | spriteMeshType: 1 47 | alignment: 0 48 | spritePivot: {x: 0.5, y: 0.5} 49 | spritePixelsToUnits: 100 50 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 51 | spriteGenerateFallbackPhysicsShape: 1 52 | alphaUsage: 1 53 | alphaIsTransparency: 1 54 | spriteTessellationDetail: -1 55 | textureType: 2 56 | textureShape: 1 57 | singleChannelComponent: 0 58 | flipbookRows: 1 59 | flipbookColumns: 1 60 | maxTextureSizeSet: 0 61 | compressionQualitySet: 0 62 | textureFormatSet: 0 63 | ignorePngGamma: 0 64 | applyGammaDecoding: 0 65 | platformSettings: 66 | - serializedVersion: 3 67 | buildTarget: DefaultTexturePlatform 68 | maxTextureSize: 2048 69 | resizeAlgorithm: 0 70 | textureFormat: -1 71 | textureCompression: 1 72 | compressionQuality: 50 73 | crunchedCompression: 0 74 | allowsAlphaSplitting: 0 75 | overridden: 0 76 | androidETC2FallbackOverride: 0 77 | forceMaximumCompressionQuality_BC6H_BC7: 0 78 | - serializedVersion: 3 79 | buildTarget: Standalone 80 | maxTextureSize: 2048 81 | resizeAlgorithm: 0 82 | textureFormat: -1 83 | textureCompression: 1 84 | compressionQuality: 50 85 | crunchedCompression: 0 86 | allowsAlphaSplitting: 0 87 | overridden: 0 88 | androidETC2FallbackOverride: 0 89 | forceMaximumCompressionQuality_BC6H_BC7: 0 90 | - serializedVersion: 3 91 | buildTarget: Android 92 | maxTextureSize: 2048 93 | resizeAlgorithm: 0 94 | textureFormat: -1 95 | textureCompression: 1 96 | compressionQuality: 50 97 | crunchedCompression: 0 98 | allowsAlphaSplitting: 0 99 | overridden: 0 100 | androidETC2FallbackOverride: 0 101 | forceMaximumCompressionQuality_BC6H_BC7: 0 102 | spriteSheet: 103 | serializedVersion: 2 104 | sprites: [] 105 | outline: [] 106 | physicsShape: [] 107 | bones: [] 108 | spriteID: 109 | internalID: 0 110 | vertices: [] 111 | indices: 112 | edges: [] 113 | weights: [] 114 | secondaryTextures: [] 115 | spritePackingTag: 116 | pSDRemoveMatte: 0 117 | pSDShowRemoveMatteOption: 0 118 | userData: 119 | assetBundleName: 120 | assetBundleVariant: 121 | -------------------------------------------------------------------------------- /FuXi/Editor/Resources/Gizmos/Fx_Asset Black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mistletoeKANO/fuxi/a8e670cf593b7854fe3b5678c0e74f62f29a432b/FuXi/Editor/Resources/Gizmos/Fx_Asset Black.png -------------------------------------------------------------------------------- /FuXi/Editor/Resources/Gizmos/Fx_Asset Black.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d9f22f7556a013b45bc660ac6f1345da 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | vTOnly: 0 27 | grayScaleToAlpha: 0 28 | generateCubemap: 6 29 | cubemapConvolution: 0 30 | seamlessCubemap: 0 31 | textureFormat: 1 32 | maxTextureSize: 2048 33 | textureSettings: 34 | serializedVersion: 2 35 | filterMode: -1 36 | aniso: 1 37 | mipBias: -100 38 | wrapU: 1 39 | wrapV: 1 40 | wrapW: -1 41 | nPOTScale: 0 42 | lightmap: 0 43 | compressionQuality: 50 44 | spriteMode: 0 45 | spriteExtrude: 1 46 | spriteMeshType: 1 47 | alignment: 0 48 | spritePivot: {x: 0.5, y: 0.5} 49 | spritePixelsToUnits: 100 50 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 51 | spriteGenerateFallbackPhysicsShape: 1 52 | alphaUsage: 1 53 | alphaIsTransparency: 1 54 | spriteTessellationDetail: -1 55 | textureType: 2 56 | textureShape: 1 57 | singleChannelComponent: 0 58 | flipbookRows: 1 59 | flipbookColumns: 1 60 | maxTextureSizeSet: 0 61 | compressionQualitySet: 0 62 | textureFormatSet: 0 63 | ignorePngGamma: 0 64 | applyGammaDecoding: 0 65 | platformSettings: 66 | - serializedVersion: 3 67 | buildTarget: DefaultTexturePlatform 68 | maxTextureSize: 2048 69 | resizeAlgorithm: 0 70 | textureFormat: -1 71 | textureCompression: 1 72 | compressionQuality: 50 73 | crunchedCompression: 0 74 | allowsAlphaSplitting: 0 75 | overridden: 0 76 | androidETC2FallbackOverride: 0 77 | forceMaximumCompressionQuality_BC6H_BC7: 0 78 | - serializedVersion: 3 79 | buildTarget: Standalone 80 | maxTextureSize: 2048 81 | resizeAlgorithm: 0 82 | textureFormat: -1 83 | textureCompression: 1 84 | compressionQuality: 50 85 | crunchedCompression: 0 86 | allowsAlphaSplitting: 0 87 | overridden: 0 88 | androidETC2FallbackOverride: 0 89 | forceMaximumCompressionQuality_BC6H_BC7: 0 90 | - serializedVersion: 3 91 | buildTarget: Android 92 | maxTextureSize: 2048 93 | resizeAlgorithm: 0 94 | textureFormat: -1 95 | textureCompression: 1 96 | compressionQuality: 50 97 | crunchedCompression: 0 98 | allowsAlphaSplitting: 0 99 | overridden: 0 100 | androidETC2FallbackOverride: 0 101 | forceMaximumCompressionQuality_BC6H_BC7: 0 102 | spriteSheet: 103 | serializedVersion: 2 104 | sprites: [] 105 | outline: [] 106 | physicsShape: [] 107 | bones: [] 108 | spriteID: 109 | internalID: 0 110 | vertices: [] 111 | indices: 112 | edges: [] 113 | weights: [] 114 | secondaryTextures: [] 115 | spritePackingTag: 116 | pSDRemoveMatte: 0 117 | pSDShowRemoveMatteOption: 0 118 | userData: 119 | assetBundleName: 120 | assetBundleVariant: 121 | -------------------------------------------------------------------------------- /FuXi/Editor/Resources/Gizmos/Fx_Asset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mistletoeKANO/fuxi/a8e670cf593b7854fe3b5678c0e74f62f29a432b/FuXi/Editor/Resources/Gizmos/Fx_Asset.png -------------------------------------------------------------------------------- /FuXi/Editor/Resources/Gizmos/Fx_Asset.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0de3dc8ec401d9547b9970fe6e9433e9 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | vTOnly: 0 27 | grayScaleToAlpha: 0 28 | generateCubemap: 6 29 | cubemapConvolution: 0 30 | seamlessCubemap: 0 31 | textureFormat: 1 32 | maxTextureSize: 2048 33 | textureSettings: 34 | serializedVersion: 2 35 | filterMode: -1 36 | aniso: 1 37 | mipBias: -100 38 | wrapU: 1 39 | wrapV: 1 40 | wrapW: -1 41 | nPOTScale: 0 42 | lightmap: 0 43 | compressionQuality: 50 44 | spriteMode: 0 45 | spriteExtrude: 1 46 | spriteMeshType: 1 47 | alignment: 0 48 | spritePivot: {x: 0.5, y: 0.5} 49 | spritePixelsToUnits: 100 50 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 51 | spriteGenerateFallbackPhysicsShape: 1 52 | alphaUsage: 1 53 | alphaIsTransparency: 1 54 | spriteTessellationDetail: -1 55 | textureType: 2 56 | textureShape: 1 57 | singleChannelComponent: 0 58 | flipbookRows: 1 59 | flipbookColumns: 1 60 | maxTextureSizeSet: 0 61 | compressionQualitySet: 0 62 | textureFormatSet: 0 63 | ignorePngGamma: 0 64 | applyGammaDecoding: 0 65 | platformSettings: 66 | - serializedVersion: 3 67 | buildTarget: DefaultTexturePlatform 68 | maxTextureSize: 2048 69 | resizeAlgorithm: 0 70 | textureFormat: -1 71 | textureCompression: 1 72 | compressionQuality: 50 73 | crunchedCompression: 0 74 | allowsAlphaSplitting: 0 75 | overridden: 0 76 | androidETC2FallbackOverride: 0 77 | forceMaximumCompressionQuality_BC6H_BC7: 0 78 | - serializedVersion: 3 79 | buildTarget: Standalone 80 | maxTextureSize: 2048 81 | resizeAlgorithm: 0 82 | textureFormat: -1 83 | textureCompression: 1 84 | compressionQuality: 50 85 | crunchedCompression: 0 86 | allowsAlphaSplitting: 0 87 | overridden: 0 88 | androidETC2FallbackOverride: 0 89 | forceMaximumCompressionQuality_BC6H_BC7: 0 90 | - serializedVersion: 3 91 | buildTarget: Android 92 | maxTextureSize: 2048 93 | resizeAlgorithm: 0 94 | textureFormat: -1 95 | textureCompression: 1 96 | compressionQuality: 50 97 | crunchedCompression: 0 98 | allowsAlphaSplitting: 0 99 | overridden: 0 100 | androidETC2FallbackOverride: 0 101 | forceMaximumCompressionQuality_BC6H_BC7: 0 102 | spriteSheet: 103 | serializedVersion: 2 104 | sprites: [] 105 | outline: [] 106 | physicsShape: [] 107 | bones: [] 108 | spriteID: 109 | internalID: 0 110 | vertices: [] 111 | indices: 112 | edges: [] 113 | weights: [] 114 | secondaryTextures: [] 115 | spritePackingTag: 116 | pSDRemoveMatte: 0 117 | pSDShowRemoveMatteOption: 0 118 | userData: 119 | assetBundleName: 120 | assetBundleVariant: 121 | -------------------------------------------------------------------------------- /FuXi/Editor/Resources/Gizmos/Fx_AssetPackage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mistletoeKANO/fuxi/a8e670cf593b7854fe3b5678c0e74f62f29a432b/FuXi/Editor/Resources/Gizmos/Fx_AssetPackage.png -------------------------------------------------------------------------------- /FuXi/Editor/Resources/Gizmos/Fx_AssetPackage.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4c76924870e4df047a472cc69fa4b065 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | vTOnly: 0 27 | grayScaleToAlpha: 0 28 | generateCubemap: 6 29 | cubemapConvolution: 0 30 | seamlessCubemap: 0 31 | textureFormat: 1 32 | maxTextureSize: 2048 33 | textureSettings: 34 | serializedVersion: 2 35 | filterMode: -1 36 | aniso: 1 37 | mipBias: -100 38 | wrapU: 1 39 | wrapV: 1 40 | wrapW: -1 41 | nPOTScale: 0 42 | lightmap: 0 43 | compressionQuality: 50 44 | spriteMode: 0 45 | spriteExtrude: 1 46 | spriteMeshType: 1 47 | alignment: 0 48 | spritePivot: {x: 0.5, y: 0.5} 49 | spritePixelsToUnits: 100 50 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 51 | spriteGenerateFallbackPhysicsShape: 1 52 | alphaUsage: 1 53 | alphaIsTransparency: 1 54 | spriteTessellationDetail: -1 55 | textureType: 2 56 | textureShape: 1 57 | singleChannelComponent: 0 58 | flipbookRows: 1 59 | flipbookColumns: 1 60 | maxTextureSizeSet: 0 61 | compressionQualitySet: 0 62 | textureFormatSet: 0 63 | ignorePngGamma: 0 64 | applyGammaDecoding: 0 65 | platformSettings: 66 | - serializedVersion: 3 67 | buildTarget: DefaultTexturePlatform 68 | maxTextureSize: 128 69 | resizeAlgorithm: 0 70 | textureFormat: -1 71 | textureCompression: 1 72 | compressionQuality: 16 73 | crunchedCompression: 1 74 | allowsAlphaSplitting: 0 75 | overridden: 0 76 | androidETC2FallbackOverride: 0 77 | forceMaximumCompressionQuality_BC6H_BC7: 0 78 | - serializedVersion: 3 79 | buildTarget: Standalone 80 | maxTextureSize: 128 81 | resizeAlgorithm: 0 82 | textureFormat: -1 83 | textureCompression: 1 84 | compressionQuality: 16 85 | crunchedCompression: 1 86 | allowsAlphaSplitting: 0 87 | overridden: 0 88 | androidETC2FallbackOverride: 0 89 | forceMaximumCompressionQuality_BC6H_BC7: 0 90 | - serializedVersion: 3 91 | buildTarget: iPhone 92 | maxTextureSize: 128 93 | resizeAlgorithm: 0 94 | textureFormat: -1 95 | textureCompression: 1 96 | compressionQuality: 16 97 | crunchedCompression: 1 98 | allowsAlphaSplitting: 0 99 | overridden: 0 100 | androidETC2FallbackOverride: 0 101 | forceMaximumCompressionQuality_BC6H_BC7: 0 102 | - serializedVersion: 3 103 | buildTarget: Android 104 | maxTextureSize: 128 105 | resizeAlgorithm: 0 106 | textureFormat: -1 107 | textureCompression: 1 108 | compressionQuality: 16 109 | crunchedCompression: 1 110 | allowsAlphaSplitting: 0 111 | overridden: 0 112 | androidETC2FallbackOverride: 0 113 | forceMaximumCompressionQuality_BC6H_BC7: 0 114 | spriteSheet: 115 | serializedVersion: 2 116 | sprites: [] 117 | outline: [] 118 | physicsShape: [] 119 | bones: [] 120 | spriteID: 121 | internalID: 0 122 | vertices: [] 123 | indices: 124 | edges: [] 125 | weights: [] 126 | secondaryTextures: [] 127 | spritePackingTag: 128 | pSDRemoveMatte: 0 129 | pSDShowRemoveMatteOption: 0 130 | userData: 131 | assetBundleName: 132 | assetBundleVariant: 133 | -------------------------------------------------------------------------------- /FuXi/Editor/Resources/Gizmos/Fx_PathMenu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mistletoeKANO/fuxi/a8e670cf593b7854fe3b5678c0e74f62f29a432b/FuXi/Editor/Resources/Gizmos/Fx_PathMenu.png -------------------------------------------------------------------------------- /FuXi/Editor/Resources/Gizmos/Fx_PathMenu.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2e982ef146afeb040a50cb8fa3987828 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | vTOnly: 0 27 | grayScaleToAlpha: 0 28 | generateCubemap: 6 29 | cubemapConvolution: 0 30 | seamlessCubemap: 0 31 | textureFormat: 1 32 | maxTextureSize: 2048 33 | textureSettings: 34 | serializedVersion: 2 35 | filterMode: -1 36 | aniso: 1 37 | mipBias: -100 38 | wrapU: 1 39 | wrapV: 1 40 | wrapW: -1 41 | nPOTScale: 0 42 | lightmap: 0 43 | compressionQuality: 50 44 | spriteMode: 0 45 | spriteExtrude: 1 46 | spriteMeshType: 1 47 | alignment: 0 48 | spritePivot: {x: 0.5, y: 0.5} 49 | spritePixelsToUnits: 100 50 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 51 | spriteGenerateFallbackPhysicsShape: 1 52 | alphaUsage: 1 53 | alphaIsTransparency: 1 54 | spriteTessellationDetail: -1 55 | textureType: 2 56 | textureShape: 1 57 | singleChannelComponent: 0 58 | flipbookRows: 1 59 | flipbookColumns: 1 60 | maxTextureSizeSet: 0 61 | compressionQualitySet: 0 62 | textureFormatSet: 0 63 | ignorePngGamma: 0 64 | applyGammaDecoding: 0 65 | platformSettings: 66 | - serializedVersion: 3 67 | buildTarget: DefaultTexturePlatform 68 | maxTextureSize: 2048 69 | resizeAlgorithm: 0 70 | textureFormat: -1 71 | textureCompression: 1 72 | compressionQuality: 50 73 | crunchedCompression: 0 74 | allowsAlphaSplitting: 0 75 | overridden: 0 76 | androidETC2FallbackOverride: 0 77 | forceMaximumCompressionQuality_BC6H_BC7: 0 78 | - serializedVersion: 3 79 | buildTarget: Standalone 80 | maxTextureSize: 2048 81 | resizeAlgorithm: 0 82 | textureFormat: -1 83 | textureCompression: 1 84 | compressionQuality: 50 85 | crunchedCompression: 0 86 | allowsAlphaSplitting: 0 87 | overridden: 0 88 | androidETC2FallbackOverride: 0 89 | forceMaximumCompressionQuality_BC6H_BC7: 0 90 | - serializedVersion: 3 91 | buildTarget: Android 92 | maxTextureSize: 2048 93 | resizeAlgorithm: 0 94 | textureFormat: -1 95 | textureCompression: 1 96 | compressionQuality: 50 97 | crunchedCompression: 0 98 | allowsAlphaSplitting: 0 99 | overridden: 0 100 | androidETC2FallbackOverride: 0 101 | forceMaximumCompressionQuality_BC6H_BC7: 0 102 | spriteSheet: 103 | serializedVersion: 2 104 | sprites: [] 105 | outline: [] 106 | physicsShape: [] 107 | bones: [] 108 | spriteID: 109 | internalID: 0 110 | vertices: [] 111 | indices: 112 | edges: [] 113 | weights: [] 114 | secondaryTextures: [] 115 | spritePackingTag: 116 | pSDRemoveMatte: 0 117 | pSDShowRemoveMatteOption: 0 118 | userData: 119 | assetBundleName: 120 | assetBundleVariant: 121 | -------------------------------------------------------------------------------- /FuXi/Editor/Resources/Gizmos/Fx_Setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mistletoeKANO/fuxi/a8e670cf593b7854fe3b5678c0e74f62f29a432b/FuXi/Editor/Resources/Gizmos/Fx_Setting.png -------------------------------------------------------------------------------- /FuXi/Editor/Resources/Gizmos/Fx_Setting.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 18af8d12037479b42a450979ecdb2fb2 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: -1 35 | aniso: 1 36 | mipBias: -100 37 | wrapU: 1 38 | wrapV: 1 39 | wrapW: -1 40 | nPOTScale: 0 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 1 53 | spriteTessellationDetail: -1 54 | textureType: 2 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | applyGammaDecoding: 0 61 | platformSettings: 62 | - serializedVersion: 3 63 | buildTarget: DefaultTexturePlatform 64 | maxTextureSize: 256 65 | resizeAlgorithm: 0 66 | textureFormat: -1 67 | textureCompression: 1 68 | compressionQuality: 50 69 | crunchedCompression: 0 70 | allowsAlphaSplitting: 0 71 | overridden: 0 72 | androidETC2FallbackOverride: 0 73 | forceMaximumCompressionQuality_BC6H_BC7: 0 74 | - serializedVersion: 3 75 | buildTarget: Standalone 76 | maxTextureSize: 256 77 | resizeAlgorithm: 0 78 | textureFormat: -1 79 | textureCompression: 1 80 | compressionQuality: 50 81 | crunchedCompression: 0 82 | allowsAlphaSplitting: 0 83 | overridden: 0 84 | androidETC2FallbackOverride: 0 85 | forceMaximumCompressionQuality_BC6H_BC7: 0 86 | - serializedVersion: 3 87 | buildTarget: iPhone 88 | maxTextureSize: 256 89 | resizeAlgorithm: 0 90 | textureFormat: -1 91 | textureCompression: 1 92 | compressionQuality: 50 93 | crunchedCompression: 0 94 | allowsAlphaSplitting: 0 95 | overridden: 0 96 | androidETC2FallbackOverride: 0 97 | forceMaximumCompressionQuality_BC6H_BC7: 0 98 | - serializedVersion: 3 99 | buildTarget: Android 100 | maxTextureSize: 256 101 | resizeAlgorithm: 0 102 | textureFormat: -1 103 | textureCompression: 1 104 | compressionQuality: 50 105 | crunchedCompression: 0 106 | allowsAlphaSplitting: 0 107 | overridden: 0 108 | androidETC2FallbackOverride: 0 109 | forceMaximumCompressionQuality_BC6H_BC7: 0 110 | spriteSheet: 111 | serializedVersion: 2 112 | sprites: [] 113 | outline: [] 114 | physicsShape: [] 115 | bones: [] 116 | spriteID: 117 | internalID: 0 118 | vertices: [] 119 | indices: 120 | edges: [] 121 | weights: [] 122 | secondaryTextures: [] 123 | spritePackingTag: 124 | pSDRemoveMatte: 0 125 | pSDShowRemoveMatteOption: 0 126 | userData: 127 | assetBundleName: 128 | assetBundleVariant: 129 | -------------------------------------------------------------------------------- /FuXi/Editor/Resources/Images.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7e055dcaeeb774549aa984e98daec524 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /FuXi/Editor/Resources/Images/Label_Bottom_Line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mistletoeKANO/fuxi/a8e670cf593b7854fe3b5678c0e74f62f29a432b/FuXi/Editor/Resources/Images/Label_Bottom_Line.png -------------------------------------------------------------------------------- /FuXi/Editor/Resources/Images/Label_Bottom_Line.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bb3d52ab30b632b48827bf582f7a30b9 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | vTOnly: 0 27 | grayScaleToAlpha: 0 28 | generateCubemap: 6 29 | cubemapConvolution: 0 30 | seamlessCubemap: 0 31 | textureFormat: 1 32 | maxTextureSize: 2048 33 | textureSettings: 34 | serializedVersion: 2 35 | filterMode: -1 36 | aniso: 1 37 | mipBias: -100 38 | wrapU: 1 39 | wrapV: 1 40 | wrapW: -1 41 | nPOTScale: 0 42 | lightmap: 0 43 | compressionQuality: 50 44 | spriteMode: 0 45 | spriteExtrude: 1 46 | spriteMeshType: 1 47 | alignment: 0 48 | spritePivot: {x: 0.5, y: 0.5} 49 | spritePixelsToUnits: 100 50 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 51 | spriteGenerateFallbackPhysicsShape: 1 52 | alphaUsage: 1 53 | alphaIsTransparency: 1 54 | spriteTessellationDetail: -1 55 | textureType: 2 56 | textureShape: 1 57 | singleChannelComponent: 0 58 | flipbookRows: 1 59 | flipbookColumns: 1 60 | maxTextureSizeSet: 0 61 | compressionQualitySet: 0 62 | textureFormatSet: 0 63 | ignorePngGamma: 0 64 | applyGammaDecoding: 0 65 | platformSettings: 66 | - serializedVersion: 3 67 | buildTarget: DefaultTexturePlatform 68 | maxTextureSize: 2048 69 | resizeAlgorithm: 0 70 | textureFormat: -1 71 | textureCompression: 1 72 | compressionQuality: 50 73 | crunchedCompression: 0 74 | allowsAlphaSplitting: 0 75 | overridden: 0 76 | androidETC2FallbackOverride: 0 77 | forceMaximumCompressionQuality_BC6H_BC7: 0 78 | - serializedVersion: 3 79 | buildTarget: Standalone 80 | maxTextureSize: 2048 81 | resizeAlgorithm: 0 82 | textureFormat: -1 83 | textureCompression: 1 84 | compressionQuality: 50 85 | crunchedCompression: 0 86 | allowsAlphaSplitting: 0 87 | overridden: 0 88 | androidETC2FallbackOverride: 0 89 | forceMaximumCompressionQuality_BC6H_BC7: 0 90 | - serializedVersion: 3 91 | buildTarget: Android 92 | maxTextureSize: 2048 93 | resizeAlgorithm: 0 94 | textureFormat: -1 95 | textureCompression: 1 96 | compressionQuality: 50 97 | crunchedCompression: 0 98 | allowsAlphaSplitting: 0 99 | overridden: 0 100 | androidETC2FallbackOverride: 0 101 | forceMaximumCompressionQuality_BC6H_BC7: 0 102 | spriteSheet: 103 | serializedVersion: 2 104 | sprites: [] 105 | outline: [] 106 | physicsShape: [] 107 | bones: [] 108 | spriteID: 109 | internalID: 0 110 | vertices: [] 111 | indices: 112 | edges: [] 113 | weights: [] 114 | secondaryTextures: [] 115 | spritePackingTag: 116 | pSDRemoveMatte: 0 117 | pSDShowRemoveMatteOption: 0 118 | userData: 119 | assetBundleName: 120 | assetBundleVariant: 121 | -------------------------------------------------------------------------------- /FuXi/Editor/Resources/Uss.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7f048ac1d2fa6d74db51ea72118b1655 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /FuXi/Editor/Resources/Uss/Fx_BuildAsset.uss: -------------------------------------------------------------------------------- 1 | .fx-buildAsset-main{ 2 | flex-grow: 1; 3 | } 4 | 5 | .fx-buildAsset-foot{ 6 | margin-top: 3px; 7 | } -------------------------------------------------------------------------------- /FuXi/Editor/Resources/Uss/Fx_BuildAsset.uss.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a84b1c7a73376134bb752bca5bf48ed8 3 | ScriptedImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 2 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0} 11 | disableValidation: 0 12 | -------------------------------------------------------------------------------- /FuXi/Editor/Resources/Uss/Fx_BundleReferenceWindow.uss: -------------------------------------------------------------------------------- 1 | .bf-toolbar{ 2 | height: 21px; 3 | min-height: 21px; 4 | border-top-width: 1px; 5 | } 6 | .bf-toolbar-enum{ 7 | width: 100px; 8 | } 9 | 10 | .bf-main-view-header{ 11 | height: 20px; 12 | min-height: 20px; 13 | max-height: 20px; 14 | background-color: rgba(0,0,0,0.76); 15 | } 16 | 17 | .bf-main-view{ 18 | flex-grow: 1; 19 | } 20 | .bf-main-view-bg{ 21 | position: absolute; 22 | width: 100%; 23 | height: 100%; 24 | background-image: resource("Fx_ReferenceView"); 25 | -unity-background-scale-mode: scale-and-crop; 26 | } 27 | 28 | .bf-main-view-scroll-view{ 29 | background-color: rgba(0,0,0,0.56); 30 | } 31 | 32 | .bf-main-view-scroll-view > Button{ 33 | padding: 0; 34 | } 35 | 36 | .bf-footer{ 37 | height: 20px; 38 | min-height: 20px; 39 | border-top-width: 1px; 40 | border-color: rgba(1, 1, 1, 0.4); 41 | } 42 | 43 | .bf-footer-label{ 44 | flex-grow: 1; 45 | height: 20px; 46 | min-height: 20px; 47 | max-height: 20px; 48 | padding-left: 6px; 49 | border-bottom-width: 1px; 50 | border-color: rgba(1, 1, 1, 0.4); 51 | -unity-text-align: middle-left; 52 | } 53 | .bf-footer-header{ 54 | flex-grow: 1; 55 | height: 20px; 56 | cursor: split-resize-up-down; 57 | } 58 | 59 | .bf-footer-view{ 60 | 61 | } -------------------------------------------------------------------------------- /FuXi/Editor/Resources/Uss/Fx_BundleReferenceWindow.uss.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5a6c0573c236d2a4cb0f3436c9d640ab 3 | ScriptedImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 2 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0} 11 | disableValidation: 0 12 | -------------------------------------------------------------------------------- /FuXi/Editor/Resources/Uss/Fx_CommonInspector.uss: -------------------------------------------------------------------------------- 1 | .fx-inspector-margins{ 2 | padding: 3px 2px 2px 2px; 3 | } -------------------------------------------------------------------------------- /FuXi/Editor/Resources/Uss/Fx_CommonInspector.uss.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a6503f2b9f2e2c34b9eb4bcd93651ca1 3 | ScriptedImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 2 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0} 11 | disableValidation: 0 12 | -------------------------------------------------------------------------------- /FuXi/Editor/Resources/Uss/Fx_VersionManagerWindow.uss: -------------------------------------------------------------------------------- 1 | .vm-toolbar{ 2 | min-height: 21px; 3 | max-height: 21px; 4 | border-top-width: 1px; 5 | } 6 | .vm-toolbar > Label{ 7 | width: 40px; 8 | -unity-text-align: middle-right; 9 | } 10 | 11 | .vm-toolbar-drop-menu{ 12 | margin: 0; 13 | min-width: 120px; 14 | } 15 | 16 | .vm-main-view{ 17 | flex-grow: 1; 18 | } 19 | 20 | .vm-main-view-bg{ 21 | position: absolute; 22 | left: 0; 23 | right: 0; 24 | top: 0; 25 | bottom: 0; 26 | background-image: resource("GameViewBackground"); 27 | -unity-slice-bottom: 10; 28 | -unity-slice-top: 20; 29 | -unity-slice-left: 20; 30 | -unity-slice-right: 20; 31 | } 32 | 33 | .vm-main-view-info{ 34 | min-width: 160px; 35 | } 36 | 37 | .vm-main-view-bundle-list{ 38 | min-width: 240px; 39 | } 40 | 41 | .unity-two-pane-split-view__dragline-anchor{ 42 | background-color: rgba(0,0,0,0.4); 43 | } 44 | 45 | .vm-footer{ 46 | padding-left: 3px; 47 | min-height: 20px; 48 | max-height: 20px; 49 | border-top-width: 1px; 50 | border-color: rgba(1, 1, 1, 0.4); 51 | -unity-text-align: middle-left; 52 | } -------------------------------------------------------------------------------- /FuXi/Editor/Resources/Uss/Fx_VersionManagerWindow.uss.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4e8b5d65e0fd6c1429cf6432cb469ebf 3 | ScriptedImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 2 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0} 11 | disableValidation: 0 12 | -------------------------------------------------------------------------------- /FuXi/Editor/Simulation.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 86d6c9d04f304c45a28f3d8191d386cf 3 | timeCreated: 1654754774 -------------------------------------------------------------------------------- /FuXi/Editor/Simulation/FxEditorAsset.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEditor; 3 | using UnityEngine; 4 | 5 | // ReSharper disable once CheckNamespace 6 | namespace FuXi.Editor 7 | { 8 | public class FxEditorAsset : FxAsset 9 | { 10 | internal static FxEditorAsset CreateEditorAsset(string path, Type type, bool immediate, Action callback) 11 | { return new FxEditorAsset(path, type, immediate, callback); } 12 | 13 | FxEditorAsset(string path, Type type, bool loadImmediate, Action callback) : base(path, type, loadImmediate, callback) { } 14 | protected override FTask Execute() 15 | { 16 | #if UNITY_EDITOR 17 | this.stackInfo = StackTraceUtility.ExtractStackTrace(); 18 | #endif 19 | var tcs = FTask.Create(true); 20 | this.m_TcsList.Add(tcs); 21 | if (FuXiManager.ManifestVC.TryGetAssetManifest(this.m_FilePath, out var _)) 22 | this.asset = AssetDatabase.LoadAssetAtPath(this.m_FilePath, this.m_Type); 23 | manifest = new AssetManifest() {Path = this.m_FilePath, HoldBundle = -1}; 24 | if (this.m_LoadImmediate) 25 | this.LoadFinished(); 26 | this.m_LoadStep = LoadSteps.LoadBundle; 27 | return tcs; 28 | } 29 | 30 | protected override void Update() 31 | { 32 | if (this.isDone) return; 33 | switch (this.m_LoadStep) 34 | { 35 | case LoadSteps.LoadBundle: 36 | this.m_LoadStep = LoadSteps.LoadAsset; 37 | break; 38 | case LoadSteps.LoadAsset: 39 | this.LoadFinished(); 40 | break; 41 | } 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /FuXi/Editor/Simulation/FxEditorAsset.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 340cdeb6c6424048ba82fa51ba263829 3 | timeCreated: 1654754794 -------------------------------------------------------------------------------- /FuXi/Editor/Simulation/FxEditorRawAsset.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace FuXi.Editor 4 | { 5 | public class FxEditorRawAsset : FxRawAsset 6 | { 7 | internal static FxEditorRawAsset CreateEditorRawAsset(string path) 8 | { return new FxEditorRawAsset(path); } 9 | 10 | private FxEditorRawAsset(string path) : base(path) { } 11 | protected override FTask Execute() 12 | { 13 | var tcs = FTask.Create(true); 14 | this.m_TcsList.Add(tcs); 15 | this.Data = File.ReadAllBytes(this.m_PathOrURL); 16 | this.m_LoadStep = LoadStep.Download; 17 | return tcs; 18 | } 19 | 20 | protected override void Update() 21 | { 22 | if (this.isDone) return; 23 | switch (m_LoadStep) 24 | { 25 | case LoadStep.Download: 26 | this.m_LoadStep = LoadStep.LoadFile; 27 | break; 28 | case LoadStep.LoadFile: 29 | this.LoadFinished(); 30 | break; 31 | } 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /FuXi/Editor/Simulation/FxEditorRawAsset.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 872314fcaf934fa7af28341e0640cc9d 3 | timeCreated: 1654945099 -------------------------------------------------------------------------------- /FuXi/Editor/Simulation/FxEditorScene.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEditor.SceneManagement; 3 | using UnityEngine.SceneManagement; 4 | 5 | // ReSharper disable once CheckNamespace 6 | namespace FuXi.Editor 7 | { 8 | public class FxEditorScene : FxScene 9 | { 10 | internal static FxEditorScene CreateEditorScene(string path, bool addition, bool immediate, Action callback) 11 | { return new FxEditorScene(path, addition, immediate, callback); } 12 | 13 | FxEditorScene(string path, bool additive, bool immediate, Action callback) : base(path, additive, immediate, callback) { } 14 | protected override FTask Execute() 15 | { 16 | this.m_Tcs = FTask.Create(true); 17 | if (null != FuXiManager.ManifestVC && !FuXiManager.ManifestVC.TryGetAssetManifest(this.m_ScenePath, out _)) 18 | { 19 | this.LoadFinished(); 20 | } 21 | else 22 | { 23 | RefreshRef(this); 24 | if (this.m_Immediate) 25 | { 26 | EditorSceneManager.LoadSceneInPlayMode(this.m_ScenePath, new LoadSceneParameters(this.m_LoadMode)); 27 | this.LoadFinished(); 28 | } 29 | else 30 | this.m_Operation = EditorSceneManager.LoadSceneAsyncInPlayMode(this.m_ScenePath, 31 | new LoadSceneParameters(this.m_LoadMode)); 32 | } 33 | return this.m_Tcs; 34 | } 35 | 36 | protected override void Update() 37 | { 38 | if (this.isDone) return; 39 | if (this.m_Operation != null) 40 | { 41 | this.m_LoadUpdate?.Invoke(this.m_Operation.progress); 42 | if (!this.m_Operation.isDone) return; 43 | } 44 | this.LoadFinished(); 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /FuXi/Editor/Simulation/FxEditorScene.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d5b9060b495e46b88add5eb9a3e6f4fd 3 | timeCreated: 1654755995 -------------------------------------------------------------------------------- /FuXi/Editor/Window.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c364beda4a7e4eeaa9242fdb35397921 3 | timeCreated: 1649401191 -------------------------------------------------------------------------------- /FuXi/Editor/Window/Fx_AssetView.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a8e50e7cd16b4dad985c76c9f6f11059 3 | timeCreated: 1655804656 -------------------------------------------------------------------------------- /FuXi/Editor/Window/Fx_BaseView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEditor.IMGUI.Controls; 3 | using UnityEngine; 4 | 5 | namespace FuXi.Editor 6 | { 7 | public abstract class Fx_BaseView : IDisposable 8 | { 9 | protected MultiColumnHeader m_MultiColumnHeader; 10 | protected MultiColumnHeaderState m_MultiColumnHeaderState; 11 | protected MultiColumnHeaderState.Column[] m_Columns; 12 | protected int columnHeight; 13 | 14 | protected float m_ColumnHeadWidth = 0f; 15 | protected Vector2 m_ScrollPos = Vector2.zero; 16 | protected Rect m_LastRect; 17 | protected bool m_IsDrawHeader = false; 18 | 19 | public abstract void Dispose(); 20 | } 21 | } -------------------------------------------------------------------------------- /FuXi/Editor/Window/Fx_BaseView.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f580454e4cb24efcaf515f7bd87d3369 3 | timeCreated: 1655804696 -------------------------------------------------------------------------------- /FuXi/Editor/Window/Fx_BundleReferenceWindow.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2477c3d052b64a4697dcf3d2e5e79c5c 3 | timeCreated: 1655777885 -------------------------------------------------------------------------------- /FuXi/Editor/Window/Fx_BundleView.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using UnityEditor; 4 | using UnityEditor.IMGUI.Controls; 5 | using UnityEngine; 6 | 7 | // ReSharper disable once CheckNamespace 8 | namespace FuXi.Editor 9 | { 10 | public class Fx_BundleView : Fx_BaseView 11 | { 12 | internal Fx_BundleView(int columnHeight) 13 | { 14 | this.columnHeight = columnHeight; 15 | this.m_Columns = new[] 16 | { 17 | new MultiColumnHeaderState.Column 18 | { 19 | headerContent = new GUIContent("-"), 20 | headerTextAlignment = TextAlignment.Center, 21 | canSort = false, 22 | width = 40, 23 | maxWidth = 60 24 | }, 25 | new MultiColumnHeaderState.Column 26 | { 27 | headerContent = new GUIContent("Bundle Name"), 28 | minWidth = 160, 29 | width = 160, 30 | }, 31 | new MultiColumnHeaderState.Column 32 | { 33 | headerContent = new GUIContent("Ref Count"), 34 | width = 80, 35 | maxWidth = 120, 36 | }, 37 | new MultiColumnHeaderState.Column 38 | { 39 | headerContent = new GUIContent("Bundle Size"), 40 | minWidth = 80, 41 | maxWidth = 120, 42 | }, 43 | }; 44 | this.m_MultiColumnHeaderState = new MultiColumnHeaderState(this.m_Columns); 45 | this.m_MultiColumnHeader = new MultiColumnHeader(this.m_MultiColumnHeaderState); 46 | this.m_MultiColumnHeader.visibleColumnsChanged += header => { header.ResizeToFit(); }; 47 | this.m_MultiColumnHeader.sortingChanged += this.SortColumn; 48 | this.m_MultiColumnHeader.ResizeToFit(); 49 | } 50 | 51 | private void SortColumn(MultiColumnHeader header) 52 | { 53 | IOrderedEnumerable> sortedDic = null; 54 | if (header.sortedColumnIndex == 1) 55 | { 56 | sortedDic = header.IsSortedAscending(header.sortedColumnIndex) 57 | ? FuXi.DependBundleLoader.UsedBundleDic.OrderBy(c => c.Key) 58 | : FuXi.DependBundleLoader.UsedBundleDic.OrderByDescending(c => c.Key); 59 | } 60 | else if (header.sortedColumnIndex == 2) 61 | { 62 | sortedDic = header.IsSortedAscending(header.sortedColumnIndex) 63 | ? FuXi.DependBundleLoader.UsedBundleDic.OrderBy(c => c.Value.fxReference.RefCount) 64 | : FuXi.DependBundleLoader.UsedBundleDic.OrderByDescending(c => c.Key); 65 | } 66 | else if (header.sortedColumnIndex == 3) 67 | { 68 | sortedDic = header.IsSortedAscending(header.sortedColumnIndex) 69 | ? FuXi.DependBundleLoader.UsedBundleDic.OrderBy(c => c.Value.size) 70 | : FuXi.DependBundleLoader.UsedBundleDic.OrderByDescending(c => c.Key); 71 | } 72 | FuXi.DependBundleLoader.UsedBundleDic = sortedDic? 73 | .ToDictionary(c => c.Key, c => c.Value); 74 | } 75 | 76 | internal void OnHeader(Rect windowRect) 77 | { 78 | Rect posRect = GUILayoutUtility.GetRect(0, float.MaxValue, 0, float.MaxValue); 79 | this.m_ColumnHeadWidth = Mathf.Max(posRect.width + this.m_ScrollPos.x, this.m_ColumnHeadWidth); 80 | Rect columnRect = new Rect(posRect) {width = this.m_ColumnHeadWidth, height = columnHeight}; 81 | this.m_MultiColumnHeader.OnGUI(columnRect, this.m_ScrollPos.x); 82 | this.m_LastRect = new Rect(windowRect); 83 | this.m_IsDrawHeader = true; 84 | } 85 | 86 | internal void OnGUI() 87 | { 88 | if (!this.m_IsDrawHeader) return; 89 | var bundleDic = FuXi.DependBundleLoader.UsedBundleDic; 90 | Rect posRect = GUILayoutUtility.GetRect(0, float.MaxValue, 0, float.MaxValue); 91 | Rect viewRect = new Rect(this.m_LastRect) 92 | { 93 | xMax = this.m_Columns.Sum(c => c.width), 94 | yMax = bundleDic.Sum(c=> columnHeight) 95 | }; 96 | Rect columnRect = new Rect(posRect) {width = this.m_ColumnHeadWidth, height = columnHeight}; 97 | this.m_ScrollPos = GUI.BeginScrollView(posRect, this.m_ScrollPos, viewRect, false, false); 98 | int index = 0; 99 | int mMaxHeight = 0; 100 | foreach (var bundle in bundleDic) 101 | { 102 | Rect rowRect = new Rect(columnRect); 103 | int columnIndex = 0; 104 | Rect bgRect = new Rect(rowRect) {y = rowRect.y + mMaxHeight, height = columnHeight}; 105 | EditorGUI.DrawRect(bgRect, index % 2 == 0 ? Fx_Style.C_ColumnDark : Fx_Style.C_ColumnLight); 106 | if (this.m_MultiColumnHeader.IsColumnVisible(columnIndex)) 107 | { 108 | int visibleColumnIndex = this.m_MultiColumnHeader.GetVisibleColumnIndex(columnIndex); 109 | Rect cRect = this.m_MultiColumnHeader.GetColumnRect(visibleColumnIndex); 110 | cRect.y = rowRect.y + mMaxHeight; 111 | GUI.Box(cRect, Fx_Style.BundleIcon); 112 | } 113 | columnIndex++; 114 | if (this.m_MultiColumnHeader.IsColumnVisible(columnIndex)) 115 | { 116 | int visibleColumnIndex = this.m_MultiColumnHeader.GetVisibleColumnIndex(columnIndex); 117 | Rect cRect = this.m_MultiColumnHeader.GetColumnRect(visibleColumnIndex); 118 | cRect.y = rowRect.y + mMaxHeight; 119 | GUI.Label(cRect, bundle.Key); 120 | } 121 | columnIndex++; 122 | if (this.m_MultiColumnHeader.IsColumnVisible(columnIndex)) 123 | { 124 | int visibleColumnIndex = this.m_MultiColumnHeader.GetVisibleColumnIndex(columnIndex); 125 | Rect cRect = this.m_MultiColumnHeader.GetColumnRect(visibleColumnIndex); 126 | cRect.y = rowRect.y + mMaxHeight; 127 | GUI.Label(cRect, bundle.Value.fxReference.RefCount.ToString()); 128 | } 129 | columnIndex++; 130 | if (this.m_MultiColumnHeader.IsColumnVisible(columnIndex)) 131 | { 132 | int visibleColumnIndex = this.m_MultiColumnHeader.GetVisibleColumnIndex(columnIndex); 133 | Rect cRect = this.m_MultiColumnHeader.GetColumnRect(visibleColumnIndex); 134 | cRect.y = rowRect.y + mMaxHeight; 135 | var formatByte = FxUtility.FormatByteTuple(bundle.Value.size); 136 | GUI.Label(cRect, formatByte.Item1); 137 | GUI.Label(cRect, formatByte.Item2, Fx_Style.ByteStyle); 138 | } 139 | index++; 140 | mMaxHeight += columnHeight; 141 | } 142 | GUI.EndScrollView(true); 143 | } 144 | 145 | public override void Dispose() { } 146 | } 147 | } -------------------------------------------------------------------------------- /FuXi/Editor/Window/Fx_BundleView.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f6e466d7f53b4a26af8eed4a9f51ca06 3 | timeCreated: 1655804081 -------------------------------------------------------------------------------- /FuXi/Editor/Window/Fx_VersionManagerWindow.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f885736d08f54deb839998c2ae01326c 3 | timeCreated: 1655967561 -------------------------------------------------------------------------------- /FuXi/LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Mono_O 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /FuXi/LICENSE.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fd767ed8296c12e48ac5d153b66fc946 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /FuXi/Readme.md: -------------------------------------------------------------------------------- 1 | 简单高效的版本资源管理解决方案! -------------------------------------------------------------------------------- /FuXi/Readme.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 467065e5f20f01046914777d5d6468d9 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /FuXi/Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 593457e6b392ca042814b4b951bb961e 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /FuXi/Runtime/AssembleInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | [assembly: AssemblyVersion("1.1.1.5")] 4 | [assembly: InternalsVisibleTo("FuXi.Editor")] 5 | [assembly: InternalsVisibleTo("FuXi.InternalAPIBridge")] -------------------------------------------------------------------------------- /FuXi/Runtime/AssembleInfo.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e737decd04c147ccac927bbf7add532a 3 | timeCreated: 1650784230 -------------------------------------------------------------------------------- /FuXi/Runtime/AssetPolling.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | // ReSharper disable once CheckNamespace 4 | namespace FuXi 5 | { 6 | public class AssetPolling : MonoBehaviour 7 | { 8 | public static float TimeSlice 9 | { 10 | get => timeSlice; 11 | set => timeSlice = value; 12 | } 13 | private static float timeSlice = 0.04f; // s 14 | private static float lastCheckTime = 0; 15 | internal static bool IsTimeOut 16 | { 17 | get 18 | { 19 | var curTime = Time.realtimeSinceStartup; 20 | if (curTime - lastCheckTime >= timeSlice) 21 | { 22 | lastCheckTime = curTime; 23 | return true; 24 | } 25 | lastCheckTime = curTime; 26 | return false; 27 | } 28 | } 29 | 30 | private void Update() 31 | { 32 | FxAsyncTask.UpdateProcess(); 33 | FxScene.UpdateUnused(); 34 | DependBundleLoader.UpdateUnUsed(); 35 | } 36 | 37 | private void OnApplicationQuit() 38 | { 39 | FxAsyncTask.ClearProcess(); 40 | DependBundleLoader.ClearBundleCache(); 41 | FxAsset.ClearAssetCache(); 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /FuXi/Runtime/AssetPolling.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e06399a706b649bd93c317c2e5f645c1 3 | timeCreated: 1651747158 -------------------------------------------------------------------------------- /FuXi/Runtime/Base.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 379f0ae1ff7c4f6288cb15aef7ed505d 3 | timeCreated: 1651892954 -------------------------------------------------------------------------------- /FuXi/Runtime/Base/FxAsyncTask.Global.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FuXi 4 | { 5 | public partial class FxAsyncTask 6 | { 7 | private static readonly List Processes = new List(); 8 | 9 | internal static void UpdateProcess() 10 | { 11 | if (Processes.Count == 0) return; 12 | for (int i = 0; i < Processes.Count; i++) 13 | { 14 | var p = Processes[i]; 15 | p.Update(); 16 | if (p.isDone) 17 | { 18 | Processes.RemoveAt(i); 19 | i--; 20 | } 21 | if (AssetPolling.IsTimeOut) break; 22 | } 23 | } 24 | 25 | internal static void ClearProcess() 26 | { 27 | if (Processes.Count == 0) return; 28 | foreach (var p in Processes) 29 | { 30 | p.Dispose(); 31 | } 32 | Processes.Clear(); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /FuXi/Runtime/Base/FxAsyncTask.Global.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d7ccc23bc6e5403abc44f5236f5f5452 3 | timeCreated: 1653448331 -------------------------------------------------------------------------------- /FuXi/Runtime/Base/FxAsyncTask.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | // ReSharper disable once CheckNamespace 3 | namespace FuXi 4 | { 5 | public partial class FxAsyncTask : IEnumerator 6 | { 7 | public bool isDone; 8 | public float progress; 9 | public string error; 10 | 11 | public bool MoveNext() => !isDone; 12 | public void Reset() { } 13 | public object Current => null; 14 | 15 | protected FxAsyncTask(bool immediate) 16 | { 17 | this.isDone = false; 18 | this.progress = 0; 19 | if (!immediate) 20 | Processes.Add(this); 21 | } 22 | 23 | protected virtual void Update() 24 | { 25 | this.isDone = true; 26 | } 27 | protected virtual void Dispose(){} 28 | } 29 | } -------------------------------------------------------------------------------- /FuXi/Runtime/Base/FxAsyncTask.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ba828b6310d445639e3d3d25d6d97b90 3 | timeCreated: 1651821224 -------------------------------------------------------------------------------- /FuXi/Runtime/Base/FxReference.cs: -------------------------------------------------------------------------------- 1 | namespace FuXi 2 | { 3 | public class FxReference 4 | { 5 | internal int RefCount; 6 | internal void AddRef() 7 | { 8 | this.RefCount++; 9 | } 10 | internal bool SubRef() 11 | { 12 | return --RefCount <= 0; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /FuXi/Runtime/Base/FxReference.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 570e225906a3477cbb52c2e6255da313 3 | timeCreated: 1654913538 -------------------------------------------------------------------------------- /FuXi/Runtime/Encrypt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f05fa697d3874f11abdbc97b641d4817 3 | timeCreated: 1654857949 -------------------------------------------------------------------------------- /FuXi/Runtime/Encrypt/BaseEncrypt.cs: -------------------------------------------------------------------------------- 1 | // ReSharper disable once CheckNamespace 2 | namespace FuXi 3 | { 4 | public abstract class BaseEncrypt 5 | { 6 | protected byte[] header; 7 | /// 8 | /// 加密头 9 | /// 10 | protected virtual string EncryptHeader => "FuXiEncrypt"; 11 | /// 12 | /// 加密模式 13 | /// 14 | public virtual EncryptMode EncryptMode => EncryptMode.OFFSET; 15 | /// 16 | /// 加密头长度 17 | /// 18 | public virtual int HeadLength { get; } 19 | /// 20 | /// 验证是否已经加密 21 | /// 22 | /// 23 | /// 24 | internal bool IsEncrypted(byte[] sourceBytes) 25 | { 26 | for (int i = 0; i < header.Length; i++) 27 | { 28 | if (header[i] != sourceBytes[i]) return false; 29 | } 30 | return true; 31 | } 32 | 33 | /// 34 | /// 加密数据,返回加密后字节数组 35 | /// 36 | /// 37 | /// 38 | public virtual byte[] Encrypt(byte[] sourceBytes) { return sourceBytes; } 39 | 40 | /// 41 | /// 返回加密字节数组, 用于OFFSET 42 | /// 43 | /// 44 | public virtual byte[] EncryptOffset(){ return null; } 45 | 46 | /// 47 | /// 解密, 用于XOR 48 | /// 49 | /// 50 | /// 51 | public virtual byte[] Decrypt(byte[] sourceBytes) { return sourceBytes; } 52 | } 53 | } -------------------------------------------------------------------------------- /FuXi/Runtime/Encrypt/BaseEncrypt.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bca930008c984a77baa6ec6fa3fdc7a7 3 | timeCreated: 1651133907 -------------------------------------------------------------------------------- /FuXi/Runtime/Encrypt/EncryptMode.cs: -------------------------------------------------------------------------------- 1 | namespace FuXi 2 | { 3 | public enum EncryptMode 4 | { 5 | /// 6 | /// 偏移加密 7 | /// 8 | OFFSET, 9 | /// 10 | /// 全字节异或加密 11 | /// 12 | XOR, 13 | } 14 | } -------------------------------------------------------------------------------- /FuXi/Runtime/Encrypt/EncryptMode.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e41ec2f707ff48e18c00e941f217f12e 3 | timeCreated: 1654858001 -------------------------------------------------------------------------------- /FuXi/Runtime/Encrypt/FxEncryptOffset.cs: -------------------------------------------------------------------------------- 1 | // ReSharper disable once CheckNamespace 2 | namespace FuXi 3 | { 4 | /// 5 | /// 伏羲内置加密, 文件头偏移加密 6 | /// 7 | [UnityEngine.Scripting.Preserve] 8 | public sealed class FxEncryptOffset : BaseEncrypt 9 | { 10 | protected override string EncryptHeader => "FxEncryptOffset"; 11 | /// 12 | /// 加密验证序列 13 | /// 14 | private readonly byte[] encryptBytes = {0xE6, 0x88, 0x91, 0xE7, 0x88, 0xB1, 0xE4, 0xB8, 0xAD, 0xE5, 0x9B, 0xBD}; 15 | 16 | public override EncryptMode EncryptMode => EncryptMode.OFFSET; 17 | 18 | public override int HeadLength => header.Length + encryptBytes.Length; 19 | 20 | public FxEncryptOffset() 21 | { 22 | header = System.Text.Encoding.UTF8.GetBytes(EncryptHeader); 23 | } 24 | 25 | public override byte[] Encrypt(byte[] sourceBytes) 26 | { 27 | if (this.IsEncrypted(sourceBytes)) return sourceBytes; 28 | byte[] buffer = new byte[sourceBytes.Length + encryptBytes.Length + header.Length]; 29 | header.CopyTo(buffer, 0); 30 | encryptBytes.CopyTo(buffer, header.Length); 31 | sourceBytes.CopyTo(buffer, header.Length + encryptBytes.Length); 32 | return buffer; 33 | } 34 | 35 | /// 36 | /// 验证加密序列 与bundle字节序列是否一致 37 | /// 38 | /// 39 | public override byte[] EncryptOffset() 40 | { 41 | byte[] buffer = new byte[header.Length + encryptBytes.Length]; 42 | header.CopyTo(buffer, 0); 43 | encryptBytes.CopyTo(buffer, header.Length); 44 | return buffer; 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /FuXi/Runtime/Encrypt/FxEncryptOffset.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 169e342ec6c244d298a2369d7b1d8463 3 | timeCreated: 1651141270 -------------------------------------------------------------------------------- /FuXi/Runtime/Encrypt/FxEncryptXor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | // ReSharper disable once CheckNamespace 4 | namespace FuXi 5 | { 6 | /// 7 | /// 伏羲内置加密, 全字节异或加密 8 | /// 9 | [UnityEngine.Scripting.Preserve] 10 | public sealed class FxEncryptXor : BaseEncrypt 11 | { 12 | protected override string EncryptHeader => "FxEncryptXOR"; 13 | 14 | /// 15 | /// 加密序列 16 | /// 17 | private readonly byte[] EncryptBytes = {0xE6, 0x88, 0x91, 0xE7, 0x88, 0xB1, 0xE4, 0xB8, 0xAD, 0xE5, 0x9B, 0xBD}; 18 | 19 | public override EncryptMode EncryptMode => EncryptMode.XOR; 20 | 21 | public FxEncryptXor() 22 | { 23 | header = System.Text.Encoding.UTF8.GetBytes(EncryptHeader); 24 | } 25 | 26 | /// 27 | /// 加密 28 | /// 29 | /// 30 | /// 31 | public override byte[] Encrypt(byte[] sourceBytes) 32 | { 33 | if (this.IsEncrypted(sourceBytes)) return sourceBytes; 34 | byte[] buffer = new byte[header.Length + sourceBytes.Length]; 35 | header.CopyTo(buffer, 0); 36 | 37 | sourceBytes = this.EncryptInternal(sourceBytes); 38 | sourceBytes.CopyTo(buffer, header.Length); 39 | 40 | return buffer; 41 | } 42 | 43 | /// 44 | /// 解密 45 | /// 46 | /// 47 | /// 48 | public override byte[] Decrypt(byte[] sourceBytes) 49 | { 50 | if (!this.IsEncrypted(sourceBytes)) return sourceBytes; 51 | byte[] buffer = new byte[sourceBytes.Length - header.Length]; 52 | Array.Copy(sourceBytes, header.Length, buffer, 0, buffer.Length); 53 | return this.EncryptInternal(buffer); 54 | } 55 | 56 | private byte[] EncryptInternal(byte[] sourceBytes) 57 | { 58 | int encLength = EncryptBytes.Length; 59 | int souLength = sourceBytes.Length; 60 | for (int i = 0; i < souLength; i++) 61 | { 62 | byte b = sourceBytes[i]; 63 | byte encXor = EncryptBytes[i % encLength]; 64 | sourceBytes[i] = Convert.ToByte(b ^ encXor); 65 | } 66 | return sourceBytes; 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /FuXi/Runtime/Encrypt/FxEncryptXor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 76e95d0210f640849e75747f4b7c2c8f 3 | timeCreated: 1654867590 -------------------------------------------------------------------------------- /FuXi/Runtime/FDownloadProcess.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2604c5add5fc444597e5738b00f35efa 3 | timeCreated: 1653359536 -------------------------------------------------------------------------------- /FuXi/Runtime/FDownloadProcess/Downloader.cs: -------------------------------------------------------------------------------- 1 | 2 | namespace FuXi 3 | { 4 | public class Downloader 5 | { 6 | internal bool isDone; 7 | internal string error; 8 | 9 | /// 10 | /// 超过规定时间下载大小 未变化 则按超时处理 11 | /// 12 | private readonly float timeout; 13 | private float curTime; 14 | private long lastDownloadSize; 15 | internal long DownloadSize => this.m_ThreadDownloader.m_DownloadedSize; 16 | 17 | private readonly ThreadDownloader m_ThreadDownloader; 18 | internal readonly BundleManifest m_BundleManifest; 19 | 20 | internal Downloader(BundleManifest bundleManifest) 21 | { 22 | this.timeout = 10; 23 | this.m_BundleManifest = bundleManifest; 24 | this.m_ThreadDownloader = new ThreadDownloader(); 25 | } 26 | 27 | internal void StartDownload() 28 | { 29 | this.m_ThreadDownloader.Start(this.m_BundleManifest); 30 | this.curTime = UnityEngine.Time.realtimeSinceStartup; 31 | } 32 | 33 | internal void Update() 34 | { 35 | if (this.isDone) 36 | return; 37 | this.isDone = this.m_ThreadDownloader.isDone; 38 | 39 | if (UnityEngine.Time.realtimeSinceStartup - this.curTime > this.timeout) 40 | { 41 | this.isDone = true; 42 | this.error = "Download timeout."; 43 | this.m_ThreadDownloader.Abort(); 44 | return; 45 | } 46 | if (this.isDone) 47 | { 48 | if (!string.IsNullOrEmpty(this.m_ThreadDownloader.error)) 49 | { 50 | this.error = this.m_ThreadDownloader.error; 51 | FxDebug.ColorError(FX_LOG_CONTROL.Red, this.m_ThreadDownloader.error); 52 | } 53 | else 54 | FxDebug.ColorLog(FX_LOG_CONTROL.Green, "Download bundle {0}", this.m_BundleManifest.BundleHashName); 55 | this.m_ThreadDownloader.Dispose(); 56 | } 57 | if (this.lastDownloadSize != DownloadSize) 58 | { 59 | this.lastDownloadSize = DownloadSize; 60 | this.curTime = UnityEngine.Time.realtimeSinceStartup; 61 | } 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /FuXi/Runtime/FDownloadProcess/Downloader.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 48a7332cc79b4512b7dfeaa349e329b6 3 | timeCreated: 1654506728 -------------------------------------------------------------------------------- /FuXi/Runtime/FDownloadProcess/ThreadDownloader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Net; 4 | using System.Net.Security; 5 | using System.Security.Cryptography.X509Certificates; 6 | using System.Threading.Tasks; 7 | 8 | namespace FuXi 9 | { 10 | public class ThreadDownloader 11 | { 12 | private const int m_BufferSize = 1024 * 4; 13 | private const string m_FtpUserName = ""; 14 | private const string m_FtpPassword = ""; 15 | 16 | private Task m_Task; 17 | private string m_URL; 18 | private string m_SavePath; 19 | 20 | private long m_MaxSize; 21 | private string m_Crc; 22 | 23 | internal string error; 24 | internal bool isDone = false; 25 | internal long m_DownloadedSize; 26 | 27 | internal void Start(BundleManifest manifest) 28 | { 29 | this.m_URL = $"{FuXiManager.PlatformURL}{manifest.BundleHashName}"; 30 | this.m_SavePath = FxPathHelper.PersistentLoadPath(manifest.BundleHashName); 31 | 32 | this.m_Crc = manifest.CRC; 33 | this.m_MaxSize = manifest.Size; 34 | this.m_DownloadedSize = 0; 35 | 36 | this.StartThread(); 37 | } 38 | 39 | private void StartThread() 40 | { 41 | this.isDone = false; 42 | this.error = String.Empty; 43 | this.m_Task = Task.Factory.StartNew(RunThread); 44 | } 45 | 46 | private async void RunThread() 47 | { 48 | FileStream fileStream = null; 49 | WebResponse response = null; 50 | Stream respStream = null; 51 | 52 | try 53 | { 54 | FileInfo fileInfo = new FileInfo(this.m_SavePath); 55 | if (fileInfo.Exists && (fileInfo.Length > this.m_MaxSize || !FuXiManager.ManifestVC.NewManifest.OpenBreakResume)) 56 | { 57 | File.Delete(this.m_SavePath); 58 | } 59 | 60 | fileStream = new FileStream(this.m_SavePath, FileMode.OpenOrCreate, FileAccess.Write); 61 | var resumeLength = fileStream.Length; 62 | // 注意:设置本地文件流的起始位置, 断点续传 63 | if (resumeLength > 0 && FuXiManager.ManifestVC.NewManifest.OpenBreakResume) 64 | fileStream.Seek(resumeLength, SeekOrigin.Begin); 65 | else 66 | resumeLength = 0; 67 | 68 | var webRequest = this.CreateWebRequest(resumeLength); 69 | if (webRequest == null) 70 | throw new WebException("创建下载请求失败"); 71 | response = await webRequest.GetResponseAsync(); 72 | respStream = response.GetResponseStream(); 73 | 74 | byte[] buffer = new byte[m_BufferSize]; 75 | while (respStream != null && !this.isDone) 76 | { 77 | int readLength = await respStream.ReadAsync(buffer, 0, buffer.Length); 78 | if (readLength <= 0) 79 | break; 80 | fileStream.Write(buffer, 0, readLength); 81 | 82 | this.m_DownloadedSize += readLength; 83 | } 84 | this.isDone = true; 85 | } 86 | catch (Exception e) 87 | { 88 | this.isDone = true; 89 | this.error = $"下载资源异常:{e.Message}"; 90 | } 91 | finally 92 | { 93 | respStream?.Close(); 94 | respStream?.Dispose(); 95 | 96 | response?.Close(); 97 | response?.Dispose(); 98 | 99 | fileStream?.Close(); 100 | fileStream?.Dispose(); 101 | 102 | this.CheckDownloadedFileValid(); 103 | this.isDone = true; 104 | } 105 | } 106 | 107 | internal void Abort() 108 | { 109 | this.isDone = true; 110 | this.m_Task?.Dispose(); 111 | } 112 | 113 | /// 114 | /// 验证下载文件完整性 115 | /// 116 | private void CheckDownloadedFileValid() 117 | { 118 | if (!File.Exists(this.m_SavePath)) 119 | { 120 | this.error = $"下载文件不存在 {this.m_URL}"; 121 | return; 122 | } 123 | 124 | long downloadSize = FxUtility.FileSize(this.m_SavePath); 125 | if (downloadSize != this.m_MaxSize) 126 | { 127 | this.error = $"下载文件 {this.m_URL} 大小不一致 {downloadSize}/{this.m_MaxSize}"; 128 | File.Delete(this.m_SavePath); 129 | return; 130 | } 131 | 132 | if (FxUtility.FileCrc32(this.m_SavePath) != this.m_Crc) 133 | { 134 | this.error = $"下载文件CRC不一致 {this.m_URL}"; 135 | File.Delete(this.m_SavePath); 136 | } 137 | } 138 | 139 | /// 140 | /// 创建下载请求 141 | /// 142 | /// 请求字节流偏移,断点续传 143 | /// 144 | private WebRequest CreateWebRequest(long offset) 145 | { 146 | if (this.m_URL.StartsWith("ftp", StringComparison.OrdinalIgnoreCase)) 147 | { 148 | var ftpRequest = (FtpWebRequest) WebRequest.Create(this.m_URL); 149 | ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile; 150 | 151 | if (!string.IsNullOrEmpty(m_FtpUserName)) 152 | { 153 | ftpRequest.Credentials = new NetworkCredential(m_FtpUserName, m_FtpPassword); 154 | } 155 | 156 | if (offset > 0) ftpRequest.ContentOffset = offset; 157 | return ftpRequest; 158 | } 159 | if (this.m_URL.StartsWith("https", StringComparison.OrdinalIgnoreCase)) 160 | { 161 | ServicePointManager.ServerCertificateValidationCallback = CheckValidationResult; 162 | } 163 | 164 | var httpRequest = (HttpWebRequest) WebRequest.Create(this.m_URL); 165 | httpRequest.ProtocolVersion = HttpVersion.Version10; 166 | if (offset > 0) httpRequest.AddRange(offset); 167 | return httpRequest; 168 | } 169 | 170 | internal void Dispose() 171 | { 172 | this.m_Task?.Dispose(); 173 | this.m_Task = null; 174 | } 175 | 176 | private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, 177 | SslPolicyErrors spe) 178 | { 179 | return true; 180 | } 181 | } 182 | } -------------------------------------------------------------------------------- /FuXi/Runtime/FDownloadProcess/ThreadDownloader.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5048b8dcd597454b94e8aded91085cfe 3 | timeCreated: 1654512219 -------------------------------------------------------------------------------- /FuXi/Runtime/FLoaderProcess.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 208b25e7321e46829d228681ebdc6f4b 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /FuXi/Runtime/FLoaderProcess/BundleLoader.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FuXi 4 | { 5 | public class BundleLoader 6 | { 7 | private enum LoadStep 8 | { 9 | CheckDownload, 10 | LoadBundle, 11 | } 12 | 13 | internal bool isDone; 14 | internal float progress; 15 | internal DependBundleLoader mainLoader; 16 | 17 | private LoadStep m_Step; 18 | private List m_Downloader; 19 | private List m_LoaderList; 20 | 21 | internal void StartLoad(AssetManifest manifest, bool immediate) 22 | { 23 | if (manifest.IsRawFile) 24 | { 25 | FxDebug.ColorError(FX_LOG_CONTROL.Orange, "Raw File {0} cant load as bundle!", manifest.Path); 26 | this.isDone = true; 27 | return; 28 | } 29 | this.m_Downloader = new List(); 30 | this.m_LoaderList = new List(); 31 | 32 | if (FuXiManager.ManifestVC.TryGetBundleManifest(manifest.HoldBundle, out var bundleManifest)) 33 | { 34 | DependBundleLoader.ReferenceBundle(bundleManifest, out this.mainLoader); 35 | this.m_LoaderList.Add(this.mainLoader); 36 | 37 | var loadPath = FuXiManager.ManifestVC.BundleRealLoadPath(bundleManifest); 38 | if (string.IsNullOrEmpty(loadPath)) 39 | this.m_Downloader.Add(new Downloader(bundleManifest)); 40 | } 41 | if (manifest.DependBundles.Length > 0) 42 | { 43 | foreach (var index in manifest.DependBundles) 44 | { 45 | if (!FuXiManager.ManifestVC.TryGetBundleManifest(index, out bundleManifest)) 46 | continue; 47 | DependBundleLoader.ReferenceBundle(bundleManifest, out var bundleLoader); 48 | this.m_LoaderList.Add(bundleLoader); 49 | 50 | var loadPath = FuXiManager.ManifestVC.BundleRealLoadPath(bundleManifest); 51 | if (string.IsNullOrEmpty(loadPath)) 52 | this.m_Downloader.Add(new Downloader(bundleManifest)); 53 | } 54 | } 55 | 56 | if (this.m_Downloader.Count > 0) 57 | { 58 | if (immediate) 59 | FxDebug.ColorError(FX_LOG_CONTROL.Red, "Asset's {0} Bundle or depend bundle is not downloaded, cant load immediate!", 60 | manifest.Path); 61 | else 62 | { 63 | foreach (var downloader in m_Downloader) 64 | downloader.StartDownload(); 65 | this.m_Step = LoadStep.CheckDownload; 66 | } 67 | } 68 | else 69 | { 70 | foreach (var loader in m_LoaderList) 71 | { 72 | loader.StartLoad(immediate); 73 | } 74 | this.m_Step = LoadStep.LoadBundle; 75 | } 76 | this.isDone = immediate; 77 | } 78 | 79 | internal void Update() 80 | { 81 | if (this.isDone) return; 82 | 83 | switch (this.m_Step) 84 | { 85 | case LoadStep.CheckDownload: 86 | bool isFinishedDownload = true; 87 | foreach (var download in m_Downloader) 88 | { 89 | if (download.isDone) continue; 90 | isFinishedDownload = false; 91 | download.Update(); 92 | } 93 | if (!isFinishedDownload) 94 | break; 95 | this.m_Downloader.Clear(); 96 | foreach (var loader in m_LoaderList) 97 | { 98 | loader.StartLoad(); 99 | } 100 | this.m_Step = LoadStep.LoadBundle; 101 | break; 102 | case LoadStep.LoadBundle: 103 | isFinishedDownload = true; 104 | float progressBase = 0.0f; 105 | foreach (var bundleLoader in m_LoaderList) 106 | { 107 | progressBase += bundleLoader.progress; 108 | if (bundleLoader.isDone) continue; 109 | bundleLoader.Update(); 110 | isFinishedDownload = false; 111 | } 112 | this.progress = progressBase / this.m_LoaderList.Count; 113 | if (!isFinishedDownload) 114 | break; 115 | this.isDone = true; 116 | break; 117 | } 118 | } 119 | 120 | internal void Release() 121 | { 122 | if (this.m_LoaderList == null) return; 123 | foreach (var refLoader in this.m_LoaderList) 124 | refLoader.SubReference(); 125 | } 126 | 127 | internal void Dispose() 128 | { 129 | this.mainLoader = null; 130 | this.m_LoaderList?.Clear(); 131 | } 132 | } 133 | } -------------------------------------------------------------------------------- /FuXi/Runtime/FLoaderProcess/BundleLoader.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 36e7eb32cf784704a1794f5bd461b488 3 | timeCreated: 1654681417 -------------------------------------------------------------------------------- /FuXi/Runtime/FLoaderProcess/DependBundleLoader.Global.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FuXi 4 | { 5 | public partial class DependBundleLoader 6 | { 7 | internal static Dictionary UsedBundleDic = new Dictionary(); 8 | private static readonly List UnUsedBundle = new List(); 9 | 10 | internal static void UpdateUnUsed() 11 | { 12 | if (UnUsedBundle.Count == 0) return; 13 | for (int i = 0; i < UnUsedBundle.Count; i++) 14 | { 15 | var bundle = UnUsedBundle[i]; 16 | if (bundle.assetBundle == null) 17 | continue; 18 | bundle.assetBundle.Unload(true); 19 | bundle.assetBundle = null; 20 | FxDebug.ColorLog(FX_LOG_CONTROL.LightCyan, "Unload bundle {0}", bundle.m_BundleManifest.BundleHashName); 21 | UnUsedBundle.RemoveAt(i); 22 | i--; 23 | if (AssetPolling.IsTimeOut) 24 | break; 25 | } 26 | } 27 | 28 | private static DependBundleLoader GetFromUnUsedCache(BundleManifest manifest) 29 | { 30 | DependBundleLoader res = default; 31 | foreach (var bundle in UnUsedBundle) 32 | { 33 | if (bundle.m_BundleManifest.BundleHashName != manifest.BundleHashName) 34 | continue; 35 | res = bundle; 36 | break; 37 | } 38 | UnUsedBundle.Remove(res); 39 | return res; 40 | } 41 | 42 | internal static void ReferenceBundle(BundleManifest manifest, out DependBundleLoader bundleLoader) 43 | { 44 | if (!UsedBundleDic.TryGetValue(manifest.BundleHashName, out bundleLoader)) 45 | { 46 | bundleLoader = GetFromUnUsedCache(manifest) ?? new DependBundleLoader(manifest); 47 | UsedBundleDic.Add(manifest.BundleHashName, bundleLoader); 48 | } 49 | bundleLoader.AddReference(); 50 | } 51 | 52 | private static void ReleaseBundleLoader(BundleManifest manifest) 53 | { 54 | if (!UsedBundleDic.ContainsKey(manifest.BundleHashName)) 55 | return; 56 | var bundleLoader = UsedBundleDic[manifest.BundleHashName]; 57 | UnUsedBundle.Add(bundleLoader); 58 | UsedBundleDic.Remove(manifest.BundleHashName); 59 | } 60 | 61 | internal static void ClearBundleCache() 62 | { 63 | UsedBundleDic.Clear(); 64 | UnUsedBundle.Clear(); 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /FuXi/Runtime/FLoaderProcess/DependBundleLoader.Global.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c372c27431ad4412bc24efecdb173afe 3 | timeCreated: 1654919366 -------------------------------------------------------------------------------- /FuXi/Runtime/FLoaderProcess/DependBundleLoader.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using UnityEngine; 3 | 4 | // ReSharper disable once CheckNamespace 5 | namespace FuXi 6 | { 7 | public partial class DependBundleLoader 8 | { 9 | internal bool isDone; 10 | internal float progress; 11 | internal AssetBundle assetBundle; 12 | internal readonly FxReference fxReference; 13 | internal long size => this.m_BundleManifest.Size; 14 | 15 | private bool isLoading; 16 | private string m_PathOrURL; 17 | private AssetBundleCreateRequest m_BundleRequest; 18 | private readonly BundleManifest m_BundleManifest; 19 | 20 | private DependBundleLoader(BundleManifest bundleManifest) 21 | { 22 | this.m_BundleManifest = bundleManifest; 23 | this.fxReference = new FxReference(); 24 | } 25 | 26 | internal void StartLoad(bool immediate = false) 27 | { 28 | if (this.isDone || this.isLoading) 29 | return; 30 | 31 | this.m_PathOrURL = FuXiManager.ManifestVC.BundleRealLoadPath(this.m_BundleManifest); 32 | 33 | if (immediate) 34 | this.LoadBundleInternal(); 35 | else 36 | this.LoadBundleAsyncInternal(); 37 | this.isDone = immediate; 38 | this.isLoading = !immediate; 39 | } 40 | 41 | internal void Update() 42 | { 43 | if (this.isDone) return; 44 | 45 | this.progress = this.m_BundleRequest.progress; 46 | if (!this.m_BundleRequest.isDone) return; 47 | if (this.m_BundleRequest.assetBundle == null) 48 | FxDebug.ColorError(FX_LOG_CONTROL.Red, "Load Bundle {0} failure.", this.m_PathOrURL); 49 | else 50 | { 51 | FxDebug.ColorLog(FX_LOG_CONTROL.Cyan, "LoadBundle {0}", this.m_PathOrURL); 52 | this.assetBundle = this.m_BundleRequest.assetBundle; 53 | } 54 | this.isDone = true; 55 | this.isLoading = false; 56 | } 57 | 58 | private void LoadBundleInternal() 59 | { 60 | if (FuXiManager.ManifestVC.GameEncrypt == null) 61 | { 62 | this.assetBundle = AssetBundle.LoadFromFile(this.m_PathOrURL, 0, 0); 63 | return; 64 | } 65 | if (FuXiManager.ManifestVC.GameEncrypt.EncryptMode == EncryptMode.OFFSET) 66 | { 67 | ulong offset = (ulong) FuXiManager.ManifestVC.GameEncrypt.HeadLength; 68 | this.assetBundle = AssetBundle.LoadFromFile(this.m_PathOrURL, 0, offset); 69 | } 70 | else if (FuXiManager.ManifestVC.GameEncrypt.EncryptMode == EncryptMode.XOR) 71 | { 72 | using (FileStream fileStream = new FileStream(this.m_PathOrURL, FileMode.Open, FileAccess.Read)) 73 | { 74 | byte[] buffer = new byte[fileStream.Length]; 75 | fileStream.Read(buffer, 0, buffer.Length); 76 | buffer = FuXiManager.ManifestVC.GameEncrypt.Decrypt(buffer); 77 | this.assetBundle = AssetBundle.LoadFromMemory(buffer, 0); 78 | } 79 | } 80 | FxDebug.ColorLog(FX_LOG_CONTROL.Cyan, "LoadBundle {0}", this.m_PathOrURL); 81 | } 82 | 83 | private void LoadBundleAsyncInternal() 84 | { 85 | if (FuXiManager.ManifestVC.GameEncrypt == null) 86 | { 87 | this.m_BundleRequest = AssetBundle.LoadFromFileAsync(this.m_PathOrURL, 0, 0); 88 | return; 89 | } 90 | if (FuXiManager.ManifestVC.GameEncrypt.EncryptMode == EncryptMode.OFFSET) 91 | { 92 | ulong offset = (ulong) FuXiManager.ManifestVC.GameEncrypt.HeadLength; 93 | this.m_BundleRequest = AssetBundle.LoadFromFileAsync(this.m_PathOrURL, 0, offset); 94 | } 95 | else if (FuXiManager.ManifestVC.GameEncrypt.EncryptMode == EncryptMode.XOR) 96 | { 97 | using (FileStream fileStream = new FileStream(this.m_PathOrURL, FileMode.Open, FileAccess.Read)) 98 | { 99 | byte[] buffer = new byte[fileStream.Length]; 100 | fileStream.Read(buffer, 0, buffer.Length); 101 | buffer = FuXiManager.ManifestVC.GameEncrypt.Decrypt(buffer); 102 | this.m_BundleRequest = AssetBundle.LoadFromMemoryAsync(buffer, 0); 103 | } 104 | } 105 | } 106 | 107 | private void AddReference() 108 | { 109 | this.fxReference.AddRef(); 110 | } 111 | 112 | internal void SubReference() 113 | { 114 | if (!this.fxReference.SubRef()) return; 115 | ReleaseBundleLoader(this.m_BundleManifest); 116 | } 117 | } 118 | } -------------------------------------------------------------------------------- /FuXi/Runtime/FLoaderProcess/DependBundleLoader.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e6491fa403da4ea2ab5e64cac1ce515c 3 | timeCreated: 1654683606 -------------------------------------------------------------------------------- /FuXi/Runtime/FLoaderProcess/FxAsset.Global.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace FuXi 5 | { 6 | public partial class FxAsset 7 | { 8 | internal static Dictionary AssetCache = new Dictionary(); 9 | internal static Func, FxAsset> FxAssetCreate; 10 | 11 | internal static FxAsset CreateAsset(string path, Type type, bool immediate, Action callback) 12 | { return new FxAsset(path, type, immediate, callback); } 13 | 14 | private static FxAsset LoadInternal(string path, Type type, bool immediate) 15 | { 16 | path = FuXiManager.ManifestVC.CombineAssetPath(path); 17 | if (!AssetCache.TryGetValue(path, out var fxAsset)) 18 | { 19 | fxAsset = FxAssetCreate.Invoke(path, type, immediate, null); 20 | fxAsset.Execute(); 21 | AssetCache.Add(path, fxAsset); 22 | }else 23 | fxAsset.ReLoad(immediate, null); 24 | fxAsset.AddReference(); 25 | return fxAsset; 26 | } 27 | 28 | private static FTask LoadAsyncInternal(string path, Type type, Action callback) 29 | { 30 | path = FuXiManager.ManifestVC.CombineAssetPath(path); 31 | FTask tcs; 32 | if (!AssetCache.TryGetValue(path, out var fxAsset)) 33 | { 34 | fxAsset = FxAssetCreate.Invoke(path, type, false, callback); 35 | tcs = fxAsset.Execute(); 36 | AssetCache.Add(path, fxAsset); 37 | }else 38 | tcs = fxAsset.ReLoad(false, callback); 39 | fxAsset.AddReference(); 40 | return tcs; 41 | } 42 | 43 | internal static void ClearAssetCache() 44 | { 45 | AssetCache.Clear(); 46 | } 47 | 48 | /// 49 | /// 同步加载 50 | /// 51 | /// 52 | /// 53 | /// 54 | public static FxAsset Load(string path) 55 | { 56 | return LoadInternal(path, typeof(T), true); 57 | } 58 | 59 | /// 60 | /// 同步加载 61 | /// 62 | /// 63 | /// 64 | /// 65 | public static FxAsset Load(string path, Type type) 66 | { 67 | return LoadInternal(path, type, true); 68 | } 69 | 70 | /// 71 | /// 异步加载 72 | /// 73 | /// 74 | /// 75 | /// 76 | public static FxAsset LoadAsyncCo(string path) 77 | { 78 | return LoadInternal(path, typeof(T), false); 79 | } 80 | 81 | public static FTask LoadAsync(string path) 82 | { 83 | return LoadAsyncInternal(path, typeof(T), null); 84 | } 85 | 86 | /// 87 | /// 异步回调加载 88 | /// 89 | /// 90 | /// 91 | /// 92 | public static void LoadAsync(string path, Type type, Action callback) 93 | { 94 | LoadAsyncInternal(path, type, callback); 95 | } 96 | } 97 | } -------------------------------------------------------------------------------- /FuXi/Runtime/FLoaderProcess/FxAsset.Global.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e84457a1f9ae4cb0b978588247c65274 3 | timeCreated: 1654678293 -------------------------------------------------------------------------------- /FuXi/Runtime/FLoaderProcess/FxAsset.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | // ReSharper disable once CheckNamespace 6 | namespace FuXi 7 | { 8 | public partial class FxAsset : FxAsyncTask 9 | { 10 | protected enum LoadSteps 11 | { 12 | LoadBundle, 13 | LoadAsset 14 | } 15 | protected bool m_LoadImmediate; 16 | protected LoadSteps m_LoadStep; 17 | protected readonly List> m_TcsList; 18 | 19 | private readonly BundleLoader m_BundleLoader; 20 | private AssetBundleRequest m_BundleRequest; 21 | private Action m_Completed; 22 | 23 | internal readonly FxReference fxReference; 24 | internal AssetManifest manifest; 25 | 26 | #if UNITY_EDITOR 27 | internal string stackInfo; 28 | #endif 29 | 30 | protected readonly string m_FilePath; 31 | protected readonly Type m_Type; 32 | public UnityEngine.Object asset; 33 | 34 | internal FxAsset(string path, Type type, bool loadImmediate, Action callback) : base(loadImmediate) 35 | { 36 | this.m_FilePath = path; 37 | this.m_Type = type; 38 | this.m_LoadImmediate = loadImmediate; 39 | this.m_Completed = callback; 40 | this.m_BundleLoader = new BundleLoader(); 41 | this.fxReference = new FxReference(); 42 | this.m_TcsList = new List>(); 43 | } 44 | 45 | private FTask ReLoad(bool loadImmediate, Action callback) 46 | { 47 | var tcs = FTask.Create(true); 48 | this.m_TcsList.Add(tcs); 49 | this.m_LoadImmediate = loadImmediate; 50 | if (callback != null) 51 | { 52 | if (this.m_Completed != null) 53 | this.m_Completed += callback; 54 | else 55 | this.m_Completed = callback; 56 | } 57 | if (this.isDone) 58 | this.LoadFinished(); 59 | return tcs; 60 | } 61 | 62 | protected virtual FTask Execute() 63 | { 64 | #if UNITY_EDITOR 65 | this.stackInfo = StackTraceUtility.ExtractStackTrace(); 66 | #endif 67 | var tcs = FTask.Create(true); 68 | this.m_TcsList.Add(tcs); 69 | if (!FuXiManager.ManifestVC.TryGetAssetManifest(this.m_FilePath, out this.manifest)) 70 | { 71 | this.LoadFinished(); 72 | AssetCache.Remove(this.m_FilePath); 73 | } 74 | this.m_BundleLoader.StartLoad(manifest, this.m_LoadImmediate); 75 | if (this.m_LoadImmediate) 76 | { 77 | if (this.m_BundleLoader.mainLoader.assetBundle != null) 78 | this.asset = this.m_BundleLoader.mainLoader.assetBundle.LoadAsset(this.m_FilePath, this.m_Type); 79 | this.LoadFinished(); 80 | } 81 | this.m_LoadStep = LoadSteps.LoadBundle; 82 | return tcs; 83 | } 84 | 85 | protected override void Update() 86 | { 87 | if (this.isDone) return; 88 | switch (this.m_LoadStep) 89 | { 90 | case LoadSteps.LoadBundle: 91 | if (!this.m_BundleLoader.isDone) 92 | { 93 | this.m_BundleLoader.Update(); 94 | return; 95 | } 96 | if (this.m_BundleLoader.mainLoader.assetBundle == null) 97 | { 98 | this.LoadFinished(); 99 | return; 100 | } 101 | this.m_BundleRequest = this.m_BundleLoader.mainLoader.assetBundle.LoadAssetAsync(this.m_FilePath, this.m_Type); 102 | this.m_LoadStep = LoadSteps.LoadAsset; 103 | break; 104 | case LoadSteps.LoadAsset: 105 | if (!this.m_BundleRequest.isDone) 106 | return; 107 | this.asset = this.m_BundleRequest.asset; 108 | this.LoadFinished(); 109 | break; 110 | } 111 | } 112 | 113 | protected void LoadFinished() 114 | { 115 | this.isDone = true; 116 | this.m_Completed?.Invoke(this); 117 | this.m_Completed = default; 118 | foreach (var task in this.m_TcsList) 119 | { 120 | task.SetResult(this); 121 | } 122 | this.m_TcsList.Clear(); 123 | } 124 | 125 | private void AddReference() 126 | { 127 | this.fxReference.AddRef(); 128 | } 129 | 130 | public void Release() 131 | { 132 | if (!this.isDone) 133 | { 134 | FxDebug.LogWarning($"Asset {this.manifest.Path} is in loading! can't release now."); 135 | return; 136 | } 137 | this.m_BundleLoader?.Release(); 138 | if (!this.fxReference.SubRef()) return; 139 | 140 | AssetCache.Remove(this.m_FilePath); 141 | this.Dispose(); 142 | } 143 | 144 | protected override void Dispose() 145 | { 146 | this.m_BundleLoader?.Dispose(); 147 | } 148 | } 149 | } -------------------------------------------------------------------------------- /FuXi/Runtime/FLoaderProcess/FxAsset.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b04bf5b57e4441c8985a181f938e9a3d 3 | timeCreated: 1654678241 -------------------------------------------------------------------------------- /FuXi/Runtime/FLoaderProcess/FxRawAsset.Global.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace FuXi 5 | { 6 | public partial class FxRawAsset 7 | { 8 | private static readonly Dictionary RawAssetCache = new Dictionary(); 9 | internal static Func FxRawAssetCreate; 10 | 11 | internal static FxRawAsset CreateRawAsset(string path) 12 | { return new FxRawAsset(path); } 13 | 14 | private static FTask ReferenceAsset(string path) 15 | { 16 | path = FuXiManager.ManifestVC.CombineAssetPath(path); 17 | FTask tcs; 18 | if (!RawAssetCache.TryGetValue(path, out var fxAsset)) 19 | { 20 | fxAsset = FxRawAssetCreate.Invoke(path); 21 | tcs = fxAsset.Execute(); 22 | RawAssetCache.Add(path, fxAsset); 23 | } 24 | else 25 | tcs = fxAsset.GetRawAsset(); 26 | return tcs; 27 | } 28 | 29 | public static void Release(FxRawAsset rawAsset) 30 | { 31 | if (!RawAssetCache.ContainsValue(rawAsset)) return; 32 | rawAsset.Dispose(); 33 | var key = string.Empty; 34 | foreach (var item in RawAssetCache) 35 | { 36 | if (item.Value != rawAsset) continue; 37 | key = item.Key; 38 | break; 39 | } 40 | RawAssetCache.Remove(key); 41 | } 42 | 43 | public static void Release(string path) 44 | { 45 | if (!RawAssetCache.TryGetValue(path, out var rawAsset)) return; 46 | rawAsset.Dispose(); 47 | RawAssetCache.Remove(path); 48 | } 49 | 50 | public static void ReleaseAll() 51 | { 52 | foreach (var rawAsset in RawAssetCache) 53 | rawAsset.Value.Dispose(); 54 | RawAssetCache.Clear(); 55 | } 56 | 57 | /// 58 | /// 异步加载 59 | /// 60 | /// 61 | /// 62 | public static FTask LoadAsync(string path) 63 | { 64 | return ReferenceAsset(path); 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /FuXi/Runtime/FLoaderProcess/FxRawAsset.Global.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d28e75ed310c4289b84881dc83576ffc 3 | timeCreated: 1654934517 -------------------------------------------------------------------------------- /FuXi/Runtime/FLoaderProcess/FxRawAsset.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine.Networking; 3 | 4 | namespace FuXi 5 | { 6 | public partial class FxRawAsset : FxAsyncTask 7 | { 8 | protected enum LoadStep 9 | { 10 | Download, 11 | LoadFile, 12 | } 13 | private Downloader m_Downloader; 14 | private UnityWebRequest m_WebRequest; 15 | private UnityWebRequestAsyncOperation m_AsyncOperation; 16 | private BundleManifest m_BundleManifest; 17 | 18 | protected readonly List> m_TcsList; 19 | protected string m_PathOrURL; 20 | protected LoadStep m_LoadStep; 21 | 22 | public byte[] Data; 23 | public string Text => System.Text.Encoding.Default.GetString(this.Data); 24 | 25 | protected FxRawAsset(string path) : base(false) 26 | { 27 | this.m_PathOrURL = path; 28 | this.m_TcsList = new List>(); 29 | } 30 | protected virtual FTask Execute() 31 | { 32 | var tcs = FTask.Create(true); 33 | this.m_TcsList.Add(tcs); 34 | if (!FuXiManager.ManifestVC.TryGetAssetManifest(this.m_PathOrURL, out var manifest)) 35 | { 36 | this.LoadFinished(); 37 | } 38 | FuXiManager.ManifestVC.TryGetBundleManifest(manifest.HoldBundle, out this.m_BundleManifest); 39 | this.m_PathOrURL = FuXiManager.ManifestVC.BundleRealLoadPath(this.m_BundleManifest, true); 40 | if (string.IsNullOrEmpty(this.m_PathOrURL)) 41 | { 42 | this.m_Downloader = new Downloader(this.m_BundleManifest); 43 | this.m_Downloader.StartDownload(); 44 | this.m_LoadStep = LoadStep.Download; 45 | } 46 | else 47 | this.LoadInternal(); 48 | return tcs; 49 | } 50 | 51 | private FTask GetRawAsset() 52 | { 53 | var tcs = FTask.Create(true); 54 | this.m_TcsList.Add(tcs); 55 | return tcs; 56 | } 57 | 58 | protected override void Update() 59 | { 60 | if (this.isDone) return; 61 | switch (this.m_LoadStep) 62 | { 63 | case LoadStep.Download: 64 | if (!this.m_Downloader.isDone) 65 | { 66 | this.m_Downloader.Update(); 67 | return; 68 | } 69 | this.LoadInternal(); 70 | break; 71 | case LoadStep.LoadFile: 72 | if (!this.m_AsyncOperation.isDone) return; 73 | this.Data = this.m_WebRequest.downloadHandler.data; 74 | if (this.Data.Length > 0) 75 | { 76 | if (FuXiManager.ManifestVC.GameEncrypt != null && FuXiManager.ManifestVC.GameEncrypt.IsEncrypted(this.Data)) 77 | { 78 | if (FuXiManager.ManifestVC.GameEncrypt.EncryptMode == EncryptMode.OFFSET) 79 | { 80 | var headerLength = FuXiManager.ManifestVC.GameEncrypt.HeadLength; 81 | int newSize = this.Data.Length - headerLength; 82 | System.Array.Copy(this.Data, headerLength, this.Data, 0, newSize); 83 | System.Array.Resize(ref this.Data, newSize); 84 | } 85 | else if (FuXiManager.ManifestVC.GameEncrypt.EncryptMode == EncryptMode.XOR) 86 | { 87 | this.Data = FuXiManager.ManifestVC.GameEncrypt.Decrypt(this.Data); 88 | } 89 | } 90 | FxDebug.ColorLog(FX_LOG_CONTROL.Cyan, "Load RawAsset {0}", this.m_PathOrURL); 91 | }else 92 | FxDebug.ColorError(FX_LOG_CONTROL.Red, "FxRawAsset read file {0} bytes failure", this.m_PathOrURL); 93 | this.LoadFinished(); 94 | break; 95 | } 96 | } 97 | 98 | private void LoadInternal() 99 | { 100 | this.m_PathOrURL = FuXiManager.ManifestVC.BundleRealLoadPath(this.m_BundleManifest, true); 101 | this.m_WebRequest = UnityWebRequest.Get(this.m_PathOrURL); 102 | this.m_AsyncOperation = this.m_WebRequest.SendWebRequest(); 103 | this.m_LoadStep = LoadStep.LoadFile; 104 | } 105 | 106 | protected void LoadFinished() 107 | { 108 | this.isDone = true; 109 | foreach (var task in this.m_TcsList) 110 | { 111 | task.SetResult(this); 112 | } 113 | this.m_TcsList.Clear(); 114 | } 115 | 116 | protected override void Dispose() 117 | { 118 | this.m_WebRequest?.Dispose(); 119 | this.m_WebRequest = null; 120 | this.Data = null; 121 | } 122 | } 123 | } -------------------------------------------------------------------------------- /FuXi/Runtime/FLoaderProcess/FxRawAsset.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e5e165ff90924e9183f7e38d5c83e4a1 3 | timeCreated: 1654934492 -------------------------------------------------------------------------------- /FuXi/Runtime/FLoaderProcess/FxScene.Global.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using UnityEngine.SceneManagement; 4 | 5 | namespace FuXi 6 | { 7 | public partial class FxScene 8 | { 9 | private static FxScene Main; 10 | private static FxScene CurrentScene; 11 | 12 | private static readonly Queue UnUsed = new Queue(); 13 | internal static Func, FxScene> FxSceneCreate; 14 | 15 | internal static FxScene CreateScene(string path, bool addition, bool immediate, Action callback) 16 | { return new FxScene(path, addition, immediate, callback); } 17 | 18 | protected static void RefreshRef(FxScene fxScene) 19 | { 20 | if (fxScene.m_LoadMode == LoadSceneMode.Additive) 21 | { 22 | Main?.m_SubScenes.Add(fxScene); 23 | fxScene.m_Parent = Main; 24 | } 25 | else 26 | { 27 | Main?.Release(); 28 | Main = fxScene; 29 | } 30 | CurrentScene = fxScene; 31 | } 32 | 33 | internal static void UpdateUnused() 34 | { 35 | if (CurrentScene == null || !CurrentScene.isDone) return; 36 | 37 | while (UnUsed.Count > 0) 38 | { 39 | UnUsed.Dequeue().UnLoad(); 40 | if (AssetPolling.IsTimeOut) break; 41 | } 42 | } 43 | 44 | /// 45 | /// 同步加载场景 46 | /// 47 | /// 48 | /// 49 | /// 50 | public static FxScene LoadScene(string path, bool additive = false) 51 | { 52 | if (CurrentScene != null && CurrentScene.m_ScenePath == path) 53 | return CurrentScene; 54 | var scene = FxSceneCreate.Invoke(path, additive, true, null); 55 | scene.Execute(); 56 | return scene; 57 | } 58 | 59 | /// 60 | /// 异步加载 61 | /// 62 | /// 63 | /// 64 | /// 65 | /// 66 | public static FTask LoadSceneAsync(string path, bool additive = false, Action callback = null) 67 | { 68 | if (CurrentScene != null && CurrentScene.m_ScenePath == path) 69 | return CurrentScene.GetScene(); 70 | var scene = FxSceneCreate.Invoke(path, additive, false, callback); 71 | return scene.Execute(); 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /FuXi/Runtime/FLoaderProcess/FxScene.Global.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a4dbb4a471034891bbf0516fdd3fd427 3 | timeCreated: 1654742529 -------------------------------------------------------------------------------- /FuXi/Runtime/FLoaderProcess/FxScene.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.SceneManagement; 5 | 6 | namespace FuXi 7 | { 8 | public partial class FxScene : FxAsyncTask 9 | { 10 | private enum LoadSceneSteps 11 | { 12 | LoadBundle, 13 | LoadScene 14 | } 15 | internal readonly string m_ScenePath; 16 | internal readonly LoadSceneMode m_LoadMode; 17 | internal readonly bool m_Immediate; 18 | internal AsyncOperation m_Operation; 19 | internal readonly Action m_LoadUpdate; 20 | protected FTask m_Tcs; 21 | 22 | private readonly List m_SubScenes = new List(); 23 | private readonly BundleLoader m_BundleLoader; 24 | 25 | private LoadSceneSteps m_LoadStep; 26 | private FxScene m_Parent; 27 | 28 | internal FxScene(string path, bool additive, bool immediate, Action callback) : base(immediate) 29 | { 30 | this.m_ScenePath = FuXiManager.ManifestVC.CombineAssetPath(path); 31 | this.m_LoadMode = additive ? LoadSceneMode.Additive : LoadSceneMode.Single; 32 | this.m_Immediate = immediate; 33 | this.m_BundleLoader = new BundleLoader(); 34 | this.m_LoadUpdate = callback; 35 | } 36 | 37 | protected virtual FTask Execute() 38 | { 39 | this.m_Tcs = FTask.Create(true); 40 | if (!FuXiManager.ManifestVC.TryGetAssetManifest(this.m_ScenePath, out var manifest)) 41 | { 42 | this.LoadFinished(); 43 | } 44 | RefreshRef(this); 45 | this.m_BundleLoader.StartLoad(manifest, this.m_Immediate); 46 | if (this.m_Immediate) 47 | { 48 | if (this.m_BundleLoader.mainLoader.assetBundle != null) 49 | SceneManager.LoadScene(this.m_ScenePath, this.m_LoadMode); 50 | this.LoadFinished(); 51 | } 52 | this.m_LoadStep = LoadSceneSteps.LoadBundle; 53 | return this.m_Tcs; 54 | } 55 | 56 | private FTask GetScene() 57 | { 58 | var tcs = FTask.Create(true); 59 | tcs.SetResult(this); 60 | return tcs; 61 | } 62 | 63 | protected override void Update() 64 | { 65 | if (this.isDone) return; 66 | switch (this.m_LoadStep) 67 | { 68 | case LoadSceneSteps.LoadBundle: 69 | this.m_LoadUpdate?.Invoke(0.5f * this.m_BundleLoader.progress); 70 | if (!this.m_BundleLoader.isDone) 71 | { 72 | this.m_BundleLoader.Update(); 73 | return; 74 | } 75 | this.m_Operation = SceneManager.LoadSceneAsync(this.m_ScenePath, this.m_LoadMode); 76 | this.m_LoadStep = LoadSceneSteps.LoadScene; 77 | break; 78 | case LoadSceneSteps.LoadScene: 79 | this.m_LoadUpdate?.Invoke(0.5f + 0.5f * this.m_Operation.progress); 80 | if (this.m_Operation.allowSceneActivation) 81 | if (!this.m_Operation.isDone) return; 82 | else 83 | if (this.m_Operation.progress < 0.9f) return; 84 | this.LoadFinished(); 85 | break; 86 | } 87 | } 88 | 89 | protected void LoadFinished() 90 | { 91 | this.isDone = true; 92 | this.m_Tcs.SetResult(this); 93 | } 94 | 95 | private void Release() 96 | { 97 | UnUsed.Enqueue(this); 98 | } 99 | 100 | private void UnLoad() 101 | { 102 | if (this.m_Parent != null) 103 | { 104 | SceneManager.UnloadSceneAsync(this.m_ScenePath); 105 | FxDebug.ColorLog(FX_LOG_CONTROL.LightCyan, "Unload scene {0}", this.m_ScenePath); 106 | } 107 | this.m_BundleLoader?.Release(); 108 | foreach (var fxScene in this.m_SubScenes) 109 | { 110 | fxScene.Release(); 111 | } 112 | this.m_SubScenes.Clear(); 113 | this.Dispose(); 114 | } 115 | 116 | protected override void Dispose() 117 | { 118 | this.m_BundleLoader?.Dispose(); 119 | } 120 | } 121 | } -------------------------------------------------------------------------------- /FuXi/Runtime/FLoaderProcess/FxScene.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bca963abd1454dd19fccb7084a7b63bc 3 | timeCreated: 1654742503 -------------------------------------------------------------------------------- /FuXi/Runtime/FTask.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8d3d7cfdd3654ca584b3e1cf9310a8bf 3 | timeCreated: 1657966297 -------------------------------------------------------------------------------- /FuXi/Runtime/FTask/AsyncFTaskMethodBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Runtime.CompilerServices; 4 | using System.Security; 5 | 6 | namespace FuXi 7 | { 8 | public struct FAsyncTaskMethodBuilder 9 | { 10 | private FTask tcs; 11 | // 1. Static Create method. 12 | [DebuggerHidden] 13 | public static FAsyncTaskMethodBuilder Create() 14 | { 15 | FAsyncTaskMethodBuilder builder = new FAsyncTaskMethodBuilder() {tcs = FTask.Create(true)}; 16 | return builder; 17 | } 18 | 19 | // 2. TaskLike Task property(void) 20 | [DebuggerHidden] 21 | public FTask Task => this.tcs; 22 | 23 | // 3. SetException 24 | [DebuggerHidden] 25 | public void SetException(Exception e) 26 | { 27 | this.tcs.SetException(e); 28 | } 29 | 30 | // 4. SetResult 31 | [DebuggerHidden] 32 | public void SetResult() 33 | { 34 | this.tcs.SetResult(); 35 | } 36 | 37 | // 5. AwaitOnCompleted 38 | [DebuggerHidden] 39 | public void AwaitOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine 40 | { 41 | awaiter.OnCompleted(stateMachine.MoveNext); 42 | } 43 | 44 | // 6. AwaitUnsafeOnCompleted 45 | [DebuggerHidden] 46 | [SecuritySafeCritical] 47 | public void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine 48 | { 49 | awaiter.OnCompleted(stateMachine.MoveNext); 50 | } 51 | 52 | // 7. Start 53 | [DebuggerHidden] 54 | public void Start(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine 55 | { 56 | stateMachine.MoveNext(); 57 | } 58 | 59 | // 8. SetStateMachine 60 | [DebuggerHidden] 61 | public void SetStateMachine(IAsyncStateMachine stateMachine) 62 | { 63 | } 64 | } 65 | public struct FAsyncTaskMethodBuilder 66 | { 67 | private FTask tcs; 68 | 69 | // 1. Static Create method. 70 | [DebuggerHidden] 71 | public static FAsyncTaskMethodBuilder Create() 72 | { 73 | FAsyncTaskMethodBuilder builder = new FAsyncTaskMethodBuilder() { tcs = FTask.Create(true) }; 74 | return builder; 75 | } 76 | 77 | // 2. TaskLike Task property. 78 | [DebuggerHidden] 79 | public FTask Task => this.tcs; 80 | 81 | // 3. SetException 82 | [DebuggerHidden] 83 | public void SetException(Exception exception) 84 | { 85 | this.tcs.SetException(exception); 86 | } 87 | 88 | // 4. SetResult 89 | [DebuggerHidden] 90 | public void SetResult(T ret) 91 | { 92 | this.tcs.SetResult(ret); 93 | } 94 | 95 | // 5. AwaitOnCompleted 96 | [DebuggerHidden] 97 | public void AwaitOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine 98 | { 99 | awaiter.OnCompleted(stateMachine.MoveNext); 100 | } 101 | 102 | // 6. AwaitUnsafeOnCompleted 103 | [DebuggerHidden] 104 | [SecuritySafeCritical] 105 | public void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine 106 | { 107 | awaiter.OnCompleted(stateMachine.MoveNext); 108 | } 109 | 110 | // 7. Start 111 | [DebuggerHidden] 112 | public void Start(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine 113 | { 114 | stateMachine.MoveNext(); 115 | } 116 | 117 | // 8. SetStateMachine 118 | [DebuggerHidden] 119 | public void SetStateMachine(IAsyncStateMachine stateMachine) 120 | { 121 | } 122 | } 123 | } -------------------------------------------------------------------------------- /FuXi/Runtime/FTask/AsyncFTaskMethodBuilder.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6d0580e9cdb24d95a84cff64f9b439d1 3 | timeCreated: 1657970834 -------------------------------------------------------------------------------- /FuXi/Runtime/FTask/AsyncMethodBuilderAttribute.cs: -------------------------------------------------------------------------------- 1 | namespace System.Runtime.CompilerServices 2 | { 3 | #pragma warning disable 0436 4 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false, AllowMultiple = false)] 5 | public sealed class AsyncMethodBuilderAttribute : Attribute 6 | { 7 | public AsyncMethodBuilderAttribute(Type builderType) 8 | { 9 | this.BuilderType = builderType; 10 | } 11 | 12 | public Type BuilderType { get; } 13 | } 14 | #pragma warning restore 15 | } -------------------------------------------------------------------------------- /FuXi/Runtime/FTask/AsyncMethodBuilderAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ac163044893f4ed8b9397bd757ee72c0 3 | timeCreated: 1657970789 -------------------------------------------------------------------------------- /FuXi/Runtime/FTask/FTask.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Runtime.CompilerServices; 5 | using System.Runtime.ExceptionServices; 6 | 7 | namespace FuXi 8 | { 9 | internal enum AwaitState 10 | { 11 | Fault, 12 | Succeed, 13 | Pending, 14 | } 15 | [AsyncMethodBuilder(typeof(FAsyncTaskMethodBuilder))] 16 | public class FTask : ICriticalNotifyCompletion 17 | { 18 | private static readonly Queue TaskPool = new Queue(); 19 | private AwaitState state = AwaitState.Pending; 20 | private bool fromPool; 21 | private object action; 22 | private FTask() { } 23 | public static FTask Create(bool fromPool = false) 24 | { 25 | if (!fromPool) return new FTask(); 26 | return TaskPool.Count == 0 ? new FTask {fromPool = true} : TaskPool.Dequeue(); 27 | } 28 | 29 | private void Recycle() 30 | { 31 | if (!this.fromPool) return; 32 | this.state = AwaitState.Pending; 33 | this.action = null; 34 | TaskPool.Enqueue(this); 35 | if (TaskPool.Count > 1000) TaskPool.Clear(); 36 | } 37 | 38 | [DebuggerHidden] 39 | public FTask GetAwaiter() { return this; } 40 | [DebuggerHidden] 41 | public bool IsCompleted => this.state != AwaitState.Pending; 42 | [DebuggerHidden] 43 | public void OnCompleted(Action continuation) 44 | { 45 | this.UnsafeOnCompleted(continuation); 46 | } 47 | [DebuggerHidden] 48 | public void UnsafeOnCompleted(Action continuation) 49 | { 50 | if (this.state != AwaitState.Pending) 51 | { 52 | continuation?.Invoke(); 53 | return; 54 | } 55 | this.action = continuation; 56 | } 57 | [DebuggerHidden] 58 | public void GetResult() 59 | { 60 | switch (this.state) 61 | { 62 | case AwaitState.Succeed: 63 | this.Recycle(); 64 | break; 65 | case AwaitState.Fault: 66 | ExceptionDispatchInfo c = this.action as ExceptionDispatchInfo; 67 | this.action = default; 68 | this.Recycle(); 69 | c?.Throw(); 70 | break; 71 | default: 72 | throw new NotSupportedException("Cant get result when no use await in this FTask."); 73 | } 74 | } 75 | [DebuggerHidden] 76 | public void SetResult() 77 | { 78 | if (this.state != AwaitState.Pending) 79 | { 80 | throw new InvalidOperationException("This FTask is finished, cant set repeated."); 81 | } 82 | this.state = AwaitState.Succeed; 83 | Action c = this.action as Action; 84 | this.action = null; 85 | c?.Invoke(); 86 | } 87 | [DebuggerHidden] 88 | public void SetException(Exception e) 89 | { 90 | if (this.state != AwaitState.Pending) 91 | { 92 | throw new InvalidOperationException("This FTask is finished, cant set repeated."); 93 | } 94 | this.state = AwaitState.Fault; 95 | Action c = this.action as Action; 96 | this.action = ExceptionDispatchInfo.Capture(e); 97 | c?.Invoke(); 98 | } 99 | } 100 | 101 | [AsyncMethodBuilder(typeof(FAsyncTaskMethodBuilder<>))] 102 | public class FTask : ICriticalNotifyCompletion 103 | { 104 | private static readonly Queue> TaskPool = new Queue>(); 105 | private AwaitState state = AwaitState.Pending; 106 | private object action; 107 | private bool fromPool; 108 | private T value; 109 | 110 | private FTask() { } 111 | public static FTask Create(bool fromPool = false) 112 | { 113 | if (!fromPool) return new FTask(); 114 | return TaskPool.Count == 0 ? new FTask{fromPool = true} : TaskPool.Dequeue(); 115 | } 116 | 117 | private void Recycle() 118 | { 119 | if (!this.fromPool) return; 120 | this.state = AwaitState.Pending; 121 | this.action = default; 122 | this.value = default; 123 | TaskPool.Enqueue(this); 124 | if (TaskPool.Count > 1000) TaskPool.Clear(); 125 | } 126 | [DebuggerHidden] 127 | public bool IsCompleted => this.state != AwaitState.Pending; 128 | [DebuggerHidden] 129 | public FTask GetAwaiter() { return this;} 130 | [DebuggerHidden] 131 | public T GetResult() 132 | { 133 | switch (this.state) 134 | { 135 | case AwaitState.Succeed: 136 | var result = this.value; 137 | this.Recycle(); 138 | return result; 139 | case AwaitState.Fault: 140 | ExceptionDispatchInfo c = this.action as ExceptionDispatchInfo; 141 | this.action = default; 142 | this.value = default; 143 | this.Recycle(); 144 | c?.Throw(); 145 | return default; 146 | default: 147 | throw new NotSupportedException("Cant get result when no use await in this FTask."); 148 | 149 | } 150 | } 151 | [DebuggerHidden] 152 | public void SetResult(T v) 153 | { 154 | if (this.state != AwaitState.Pending) 155 | { 156 | throw new InvalidOperationException("This FTask is finished, cant set repeated."); 157 | } 158 | this.value = v; 159 | this.state = AwaitState.Succeed; 160 | var ac = this.action as Action; 161 | this.action = default; 162 | ac?.Invoke(); 163 | } 164 | [DebuggerHidden] 165 | public void SetException(Exception e) 166 | { 167 | if (this.state != AwaitState.Pending) 168 | { 169 | throw new InvalidOperationException("This FTask is finished, cant set repeated."); 170 | } 171 | this.state = AwaitState.Fault; 172 | var ac = this.action as Action; 173 | this.action = ExceptionDispatchInfo.Capture(e); 174 | ac?.Invoke(); 175 | } 176 | [DebuggerHidden] 177 | public void OnCompleted(Action continuation) 178 | { 179 | this.UnsafeOnCompleted(continuation); 180 | } 181 | [DebuggerHidden] 182 | public void UnsafeOnCompleted(Action continuation) 183 | { 184 | if (this.state != AwaitState.Pending) 185 | { 186 | continuation?.Invoke(); 187 | return; 188 | } 189 | this.action = continuation; 190 | } 191 | } 192 | } -------------------------------------------------------------------------------- /FuXi/Runtime/FTask/FTask.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0bfa1e61c3c7484d82bcc351db178700 3 | timeCreated: 1657966308 -------------------------------------------------------------------------------- /FuXi/Runtime/FUpdateProcess.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f777bd4e5fef408daf5c67efc08b7af9 3 | timeCreated: 1651821159 -------------------------------------------------------------------------------- /FuXi/Runtime/FUpdateProcess/CheckDownloadBundle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace FuXi 5 | { 6 | public class CheckDownloadBundle : FxAsyncTask 7 | { 8 | private enum CheckDownloadStep 9 | { 10 | Downloading, 11 | Finished, 12 | } 13 | 14 | private readonly Action m_CheckDownload; 15 | private readonly Queue m_BundleList; 16 | private List m_Downloading; 17 | private List m_DownloadFinished; 18 | private List m_Temp; 19 | private FTask tcs; 20 | 21 | private CheckDownloadStep m_DownloadStep; 22 | 23 | /// 24 | /// 最大同时下载个数 25 | /// 26 | private readonly int m_MaxDownloadCount; 27 | private readonly long m_DownloadSize; 28 | private long m_CurDownloadSize; 29 | 30 | public int DownloadCount => this.m_BundleList.Count; 31 | public int DownloadedCount => this.m_DownloadFinished.Count; 32 | public long DownloadSize => this.m_DownloadSize; 33 | public long DownloadedSize => this.m_CurDownloadSize; 34 | public string FormatDownloadSize => FxUtility.FormatBytes(this.m_DownloadSize); 35 | public string FormatCurDownloadSize => FxUtility.FormatBytes(this.m_CurDownloadSize); 36 | 37 | internal CheckDownloadBundle(DownloadInfo downloadInfo, Action checkDownload) : base(false) 38 | { 39 | this.m_BundleList = downloadInfo.DownloadList; 40 | this.m_DownloadSize = downloadInfo.DownloadSize; 41 | this.m_MaxDownloadCount = 6; 42 | this.m_CheckDownload = checkDownload; 43 | this.m_Downloading = new List(this.m_MaxDownloadCount); 44 | this.m_DownloadFinished = new List(); 45 | this.m_Temp = new List(); 46 | } 47 | 48 | internal FTask Execute() 49 | { 50 | tcs = FTask.Create(true); 51 | this.m_CurDownloadSize = 0; 52 | this.m_DownloadStep = CheckDownloadStep.Downloading; 53 | return this.tcs; 54 | } 55 | 56 | protected override void Update() 57 | { 58 | if (this.isDone) return; 59 | 60 | switch (this.m_DownloadStep) 61 | { 62 | case CheckDownloadStep.Downloading: 63 | while (this.m_Downloading.Count < this.m_MaxDownloadCount && this.m_BundleList.Count > 0) 64 | { 65 | if (UnityEngine.Application.internetReachability == UnityEngine.NetworkReachability.NotReachable) 66 | break; 67 | var d = new Downloader(this.m_BundleList.Dequeue()); 68 | this.m_Downloading.Add(d); 69 | d.StartDownload(); 70 | } 71 | 72 | this.m_CurDownloadSize = 0; 73 | foreach (var d in this.m_DownloadFinished) 74 | { 75 | this.m_CurDownloadSize += d.DownloadSize; 76 | } 77 | 78 | foreach (var downloader in this.m_Downloading) 79 | { 80 | this.m_CurDownloadSize += downloader.DownloadSize; 81 | downloader.Update(); 82 | if (!downloader.isDone) continue; 83 | 84 | this.m_Temp.Add(downloader); 85 | if (string.IsNullOrEmpty(downloader.error)) 86 | this.m_DownloadFinished.Add(downloader); 87 | else 88 | this.m_BundleList.Enqueue(downloader.m_BundleManifest); 89 | } 90 | foreach (var down in m_Temp) 91 | this.m_Downloading.Remove(down); 92 | this.m_Temp.Clear(); 93 | 94 | this.progress = (float) this.m_CurDownloadSize / (float) this.m_DownloadSize; 95 | this.m_CheckDownload?.Invoke(this); 96 | 97 | if (this.m_Downloading.Count <= 0 && this.m_BundleList.Count <= 0) 98 | this.m_DownloadStep = CheckDownloadStep.Finished; 99 | break; 100 | case CheckDownloadStep.Finished: 101 | FuXiManager.ManifestVC.OverrideManifest(); 102 | this.progress = 1.0f; 103 | this.tcs.SetResult(this); 104 | this.isDone = true; 105 | break; 106 | } 107 | } 108 | 109 | protected override void Dispose() 110 | { 111 | base.Dispose(); 112 | this.m_Downloading.Clear(); 113 | this.m_DownloadFinished.Clear(); 114 | this.m_BundleList.Clear(); 115 | this.m_Temp.Clear(); 116 | 117 | this.m_Downloading = null; 118 | this.m_DownloadFinished = null; 119 | this.m_Temp = null; 120 | } 121 | } 122 | } -------------------------------------------------------------------------------- /FuXi/Runtime/FUpdateProcess/CheckDownloadBundle.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c446d486a2b54c71aa9054d0a3bd1705 3 | timeCreated: 1654141136 -------------------------------------------------------------------------------- /FuXi/Runtime/FUpdateProcess/CheckDownloadSize.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace FuXi 5 | { 6 | public class CheckDownloadSize : FxAsyncTask 7 | { 8 | private enum CheckSteps 9 | { 10 | CheckNormal, 11 | CheckPackage, 12 | checkValid, 13 | Finished 14 | } 15 | 16 | public DownloadInfo DownloadInfo; 17 | private Action m_CheckUpdate; 18 | private CheckSteps m_CheckStep; 19 | private readonly bool m_ContainsPackage = false; 20 | private string[] m_Packages; 21 | private Queue m_BundleManifest; 22 | private FTask tcs; 23 | 24 | internal CheckDownloadSize(bool containsPackage = true, Action action = null) : base(false) 25 | { 26 | this.m_BundleManifest = new Queue(); 27 | this.m_ContainsPackage = containsPackage; 28 | this.m_CheckUpdate = action; 29 | } 30 | 31 | internal CheckDownloadSize(string[] package, Action action = null) : base(false) 32 | { 33 | this.m_BundleManifest = new Queue(); 34 | this.m_Packages = package; 35 | this.m_CheckUpdate = action; 36 | } 37 | 38 | internal FTask Execute() 39 | { 40 | tcs = FTask.Create(true); 41 | this.DownloadInfo = new DownloadInfo{DownloadList = new Queue()}; 42 | this.m_CheckStep = null != this.m_Packages ? CheckSteps.CheckPackage : CheckSteps.CheckNormal; 43 | if (FuXiManager.ManifestVC.NewManifest.Bundles == null) 44 | this.m_CheckStep = CheckSteps.Finished; 45 | return tcs; 46 | } 47 | 48 | protected override void Update() 49 | { 50 | if (this.isDone) return; 51 | switch (this.m_CheckStep) 52 | { 53 | case CheckSteps.CheckNormal: 54 | if (this.m_ContainsPackage) 55 | { 56 | foreach (var m in FuXiManager.ManifestVC.NewManifest.Bundles) 57 | this.m_BundleManifest.Enqueue(m); 58 | } 59 | else 60 | { 61 | var packageBundles = FuXiManager.ManifestVC.GetPackagesBundle(); 62 | int length = FuXiManager.ManifestVC.NewManifest.Bundles.Length; 63 | for (int i = 0; i < length; i++) 64 | { 65 | if (packageBundles.Contains(i)) continue; 66 | var bd = FuXiManager.ManifestVC.NewManifest.Bundles[i]; 67 | if (this.m_BundleManifest.Contains(bd)) 68 | continue; 69 | this.m_BundleManifest.Enqueue(bd); 70 | } 71 | } 72 | this.progress = 0.1f; 73 | this.m_CheckUpdate?.Invoke(this.progress); 74 | this.m_CheckStep = CheckSteps.checkValid; 75 | break; 76 | case CheckSteps.CheckPackage: 77 | if (this.m_Packages.Length == 0) 78 | { 79 | this.m_CheckStep = CheckSteps.Finished; 80 | break; 81 | } 82 | List ids = FuXiManager.ManifestVC.GetPackagesBundle(this.m_Packages); 83 | foreach (var i in ids) 84 | { 85 | this.m_BundleManifest.Enqueue(FuXiManager.ManifestVC.NewManifest.Bundles[i]); 86 | } 87 | this.progress = 0.1f; 88 | this.m_CheckUpdate?.Invoke(this.progress); 89 | this.m_CheckStep = CheckSteps.checkValid; 90 | break; 91 | case CheckSteps.checkValid: 92 | while (this.m_BundleManifest.Count > 0) 93 | { 94 | var bm = this.m_BundleManifest.Dequeue(); 95 | var downloadState = FuXiManager.ManifestVC.Downloaded(bm.BundleHashName); 96 | if (downloadState.Valid) 97 | { 98 | continue; 99 | } 100 | if (FuXiManager.ManifestVC.NewManifest.OpenBreakResume) 101 | this.DownloadInfo.DownloadSize += bm.Size - downloadState.Size; 102 | else 103 | this.DownloadInfo.DownloadSize += bm.Size; 104 | this.DownloadInfo.DownloadList.Enqueue(bm); 105 | } 106 | this.m_CheckStep = CheckSteps.Finished; 107 | break; 108 | case CheckSteps.Finished: 109 | this.progress = 1f; 110 | this.m_CheckUpdate?.Invoke(this.progress); 111 | this.tcs.SetResult(this); 112 | this.isDone = true; 113 | break; 114 | } 115 | } 116 | 117 | protected override void Dispose() 118 | { 119 | this.m_BundleManifest.Clear(); 120 | this.m_CheckUpdate = null; 121 | this.m_Packages = null; 122 | } 123 | } 124 | } -------------------------------------------------------------------------------- /FuXi/Runtime/FUpdateProcess/CheckDownloadSize.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: eb7434524d264ba5821d29e62d0381aa 3 | timeCreated: 1654141200 -------------------------------------------------------------------------------- /FuXi/Runtime/FUpdateProcess/CheckLocalManifest.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine.Networking; 2 | 3 | // ReSharper disable once CheckNamespace 4 | namespace FuXi 5 | { 6 | public class CheckLocalManifest : FxAsyncTask 7 | { 8 | private enum CheckLocalMStep 9 | { 10 | LoadFile, 11 | ParseManifest, 12 | } 13 | 14 | private UnityWebRequestAsyncOperation m_AsyncOperation; 15 | private UnityWebRequest m_UnityWebRequest; 16 | private string m_UrlOrPath; 17 | private CheckLocalMStep m_Step; 18 | private FTask tcs; 19 | 20 | internal CheckLocalManifest() : base(false) { } 21 | internal FTask Execute() 22 | { 23 | tcs = FTask.Create(true); 24 | var manifestPath = FxPathHelper.PersistentLoadPath(FuXiManager.ManifestVC.ManifestName); 25 | if (!System.IO.File.Exists(manifestPath)) 26 | manifestPath = FxPathHelper.StreamingLoadURL(FuXiManager.ManifestVC.ManifestName); 27 | else 28 | manifestPath = FxPathHelper.PersistentLoadURL(FuXiManager.ManifestVC.ManifestName); 29 | this.m_UrlOrPath = manifestPath; 30 | this.m_Step = CheckLocalMStep.LoadFile; 31 | return tcs; 32 | } 33 | 34 | protected override void Update() 35 | { 36 | if (this.isDone) return; 37 | 38 | switch (this.m_Step) 39 | { 40 | case CheckLocalMStep.LoadFile: 41 | this.m_UnityWebRequest = UnityWebRequest.Get(this.m_UrlOrPath); 42 | this.m_UnityWebRequest.disposeDownloadHandlerOnDispose = true; 43 | this.m_UnityWebRequest.timeout = 60; 44 | this.m_AsyncOperation = this.m_UnityWebRequest.SendWebRequest(); 45 | this.m_Step = CheckLocalMStep.ParseManifest; 46 | break; 47 | case CheckLocalMStep.ParseManifest: 48 | this.progress = this.m_AsyncOperation.progress; 49 | if (!this.m_UnityWebRequest.isDone) return; 50 | if (string.IsNullOrEmpty(this.m_UnityWebRequest.error)) 51 | { 52 | FxDebug.ColorLog(FX_LOG_CONTROL.Orange, "Load Local manifest file: {0}", this.m_UrlOrPath); 53 | var readValue = System.Text.Encoding.UTF8.GetString(this.m_UnityWebRequest.downloadHandler.data); 54 | FuXiManager.ManifestVC.OldManifest = FxManifest.Parse(readValue); 55 | FuXiManager.ManifestVC.NewManifest = FuXiManager.ManifestVC.OldManifest; 56 | } 57 | else 58 | { 59 | FxDebug.ColorError(FX_LOG_CONTROL.Red, "Load Local manifest file {0} failure with error: {1}!", 60 | this.m_UrlOrPath, this.m_UnityWebRequest.error); 61 | FuXiManager.ManifestVC.OldManifest = new FxManifest(); 62 | FuXiManager.ManifestVC.NewManifest = new FxManifest(); 63 | } 64 | FuXiManager.ManifestVC.InitEncrypt(); 65 | this.tcs.SetResult(this); 66 | this.isDone = true; 67 | break; 68 | } 69 | } 70 | 71 | protected override void Dispose() 72 | { 73 | if (this.m_UnityWebRequest == null) 74 | return; 75 | 76 | this.m_UnityWebRequest.Dispose(); 77 | this.m_UnityWebRequest = null; 78 | this.m_AsyncOperation = null; 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /FuXi/Runtime/FUpdateProcess/CheckLocalManifest.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2e7b3a093c5f446cbcdc79867b929971 3 | timeCreated: 1653289946 -------------------------------------------------------------------------------- /FuXi/Runtime/FUpdateProcess/CheckWWWManifest.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 49ecf0ff705d493ab82d00c8aa4e91d0 3 | timeCreated: 1653289978 -------------------------------------------------------------------------------- /FuXi/Runtime/FuXiManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9385d750d5f04ef3bf86011fb044c788 3 | timeCreated: 1651747285 -------------------------------------------------------------------------------- /FuXi/Runtime/Fx_Runtime.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "FuXi", 3 | "rootNamespace": "", 4 | "references": [], 5 | "includePlatforms": [], 6 | "excludePlatforms": [], 7 | "allowUnsafeCode": false, 8 | "overrideReferences": false, 9 | "precompiledReferences": [], 10 | "autoReferenced": true, 11 | "defineConstraints": [], 12 | "versionDefines": [], 13 | "noEngineReferences": false 14 | } -------------------------------------------------------------------------------- /FuXi/Runtime/Fx_Runtime.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1c64a098c7bf73e4ba2651fb3807a7f4 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /FuXi/Runtime/Helper.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f2b5f5c8c9144defb33ca41eb4e33951 3 | timeCreated: 1650941585 -------------------------------------------------------------------------------- /FuXi/Runtime/Helper/Crc32Algorithm.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 015be01675c34fb0b91368b263735294 3 | timeCreated: 1651053734 -------------------------------------------------------------------------------- /FuXi/Runtime/Helper/FxDebug.cs: -------------------------------------------------------------------------------- 1 | // ReSharper disable once CheckNamespace 2 | 3 | using UnityEngine; 4 | 5 | namespace FuXi 6 | { 7 | public struct FX_LOG_CONTROL 8 | { 9 | public static FX_LOG_TYPE LogLevel = FX_LOG_TYPE.LOG | FX_LOG_TYPE.WARNING | FX_LOG_TYPE.ERROR; 10 | 11 | public static UnityEngine.Color Red = UnityEngine.Color.red; 12 | public static UnityEngine.Color Green = new Color(0.01f, 0.38f, 0f); 13 | public static UnityEngine.Color Cyan = new Color(0f, 0.57f, 0.57f); 14 | public static UnityEngine.Color LightCyan = new Color(0.22f, 0.32f, 0.3f); 15 | public static UnityEngine.Color Orange = new UnityEngine.Color(1f, 0.35f, 0f); 16 | } 17 | 18 | [System.Flags] 19 | public enum FX_LOG_TYPE : byte 20 | { 21 | LOG = 1 << 0, 22 | WARNING = 1 << 1, 23 | ERROR = 1 << 2, 24 | } 25 | 26 | internal static class FxDebug 27 | { 28 | private static System.Diagnostics.Stopwatch mStopWatch; 29 | [System.Diagnostics.DebuggerHidden] 30 | internal static void Log(string message, params object[] args) 31 | { 32 | if ((FX_LOG_CONTROL.LogLevel & FX_LOG_TYPE.LOG) == 0) return; 33 | var msg = args.Length == 0 ? message : string.Format(message, args); 34 | UnityEngine.Debug.Log($"Frame {UnityEngine.Time.frameCount} -- {msg}"); 35 | } 36 | 37 | [System.Diagnostics.DebuggerHidden] 38 | internal static void LogWarning(string message, params object[] args) 39 | { 40 | if ((FX_LOG_CONTROL.LogLevel & FX_LOG_TYPE.WARNING) == 0) return; 41 | var msg = args.Length == 0 ? message : string.Format(message, args); 42 | UnityEngine.Debug.LogWarning($"Frame {UnityEngine.Time.frameCount} -- {msg}"); 43 | } 44 | [System.Diagnostics.DebuggerHidden] 45 | internal static void LogError(string message, params object[] args) 46 | { 47 | if ((FX_LOG_CONTROL.LogLevel & FX_LOG_TYPE.ERROR) == 0) return; 48 | var msg = args.Length == 0 ? message : string.Format(message, args); 49 | UnityEngine.Debug.LogError($"Frame {UnityEngine.Time.frameCount} -- {msg}"); 50 | } 51 | [System.Diagnostics.DebuggerHidden] 52 | internal static void ColorLog(UnityEngine.Color color, string message, params object[] args) 53 | { 54 | if ((FX_LOG_CONTROL.LogLevel & FX_LOG_TYPE.LOG) == 0) return; 55 | var colorFormat = UnityEngine.ColorUtility.ToHtmlStringRGBA(color); 56 | if (args.Length == 0) 57 | { 58 | Log($"{message}"); 59 | return; 60 | } 61 | for (int i = 0; i < args.Length; i++) 62 | args[i] = $"{args[i]}"; 63 | Log(message, args); 64 | } 65 | [System.Diagnostics.DebuggerHidden] 66 | internal static void ColorWarning(UnityEngine.Color color, string message, params object[] args) 67 | { 68 | if ((FX_LOG_CONTROL.LogLevel & FX_LOG_TYPE.WARNING) == 0) return; 69 | var colorFormat = UnityEngine.ColorUtility.ToHtmlStringRGBA(color); 70 | if (args.Length == 0) 71 | { 72 | LogWarning($"{message}"); 73 | return; 74 | } 75 | for (int i = 0; i < args.Length; i++) 76 | args[i] = $"{args[i]}"; 77 | LogWarning(message, args); 78 | } 79 | [System.Diagnostics.DebuggerHidden] 80 | internal static void ColorError(UnityEngine.Color color, string message, params object[] args) 81 | { 82 | if ((FX_LOG_CONTROL.LogLevel & FX_LOG_TYPE.ERROR) == 0) return; 83 | var colorFormat = UnityEngine.ColorUtility.ToHtmlStringRGBA(color); 84 | if (args.Length == 0) 85 | { 86 | LogError($"{message}"); 87 | return; 88 | } 89 | for (int i = 0; i < args.Length; i++) 90 | args[i] = $"{args[i]}"; 91 | LogError(message, args); 92 | } 93 | [System.Diagnostics.DebuggerHidden] 94 | internal static void StartWatch() 95 | { 96 | if (null == mStopWatch) 97 | mStopWatch = System.Diagnostics.Stopwatch.StartNew(); 98 | mStopWatch.Restart(); 99 | } 100 | [System.Diagnostics.DebuggerHidden] 101 | internal static void Watch(string title) 102 | { 103 | ColorLog(FX_LOG_CONTROL.Orange,$"{title}耗时: {0} ms", mStopWatch.ElapsedMilliseconds); 104 | } 105 | [System.Diagnostics.DebuggerHidden] 106 | internal static void StopWatch(string title) 107 | { 108 | mStopWatch.Stop(); 109 | ColorLog(FX_LOG_CONTROL.Orange,$"{title}耗时: {0} ms", mStopWatch.ElapsedMilliseconds); 110 | } 111 | } 112 | } -------------------------------------------------------------------------------- /FuXi/Runtime/Helper/FxDebug.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 87d3ce6c51194e418c258a5883e889d0 3 | timeCreated: 1650613759 -------------------------------------------------------------------------------- /FuXi/Runtime/Helper/FxHelper.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using UnityEngine; 3 | 4 | // ReSharper disable once CheckNamespace 5 | namespace FuXi 6 | { 7 | internal static class FxPathHelper 8 | { 9 | internal static readonly string ManifestFileExtension = ".json"; 10 | internal static readonly string VersionFileExtension = ".hash"; 11 | 12 | internal static readonly string BundlePathName = "Bundles"; 13 | private static readonly string BundleCacheDir = "BundleCache"; 14 | 15 | /// 16 | /// 获取规范化的路径 17 | /// 18 | private static string GetRegularPath(string path) 19 | { 20 | return path.Replace('\\', '/').Replace("\\", "/"); 21 | } 22 | 23 | /// 24 | /// 获取文件所在的目录路径(Linux格式) 25 | /// 26 | internal static string GetDirectory(string filePath) 27 | { 28 | string directory = Path.GetDirectoryName(filePath); 29 | return GetRegularPath(directory); 30 | } 31 | 32 | /// 33 | /// 获取基于流文件夹的加载路径 34 | /// 35 | internal static string StreamingLoadPath(string path) 36 | { 37 | return $"{StreamingRootPath()}/{path}"; 38 | } 39 | 40 | internal static string StreamingLoadURL(string path) 41 | { 42 | var strPath = StreamingLoadPath(path); 43 | switch (Application.platform) 44 | { 45 | case RuntimePlatform.Android: 46 | return strPath; 47 | case RuntimePlatform.WindowsPlayer: 48 | case RuntimePlatform.WindowsEditor: 49 | return $"file:///{strPath}"; 50 | case RuntimePlatform.IPhonePlayer: 51 | case RuntimePlatform.OSXPlayer: 52 | case RuntimePlatform.OSXEditor: 53 | return $"file://{strPath}"; 54 | } 55 | return strPath; 56 | } 57 | 58 | private static string streamingRootPath; 59 | private static string StreamingRootPath() 60 | { 61 | if (string.IsNullOrEmpty(streamingRootPath)) 62 | { 63 | streamingRootPath = $"{UnityEngine.Application.streamingAssetsPath}/{BundlePathName}"; 64 | } 65 | return streamingRootPath; 66 | } 67 | 68 | /// 69 | /// 获取基于bundle缓存文件夹的加载路径 70 | /// 71 | internal static string PersistentLoadPath(string path) 72 | { 73 | return $"{PersistentRootPath()}/{path}"; 74 | } 75 | 76 | internal static string PersistentLoadURL(string path) 77 | { 78 | var perStr = PersistentLoadPath(path); 79 | switch (Application.platform) 80 | { 81 | case RuntimePlatform.Android: 82 | return $"file://{perStr}"; 83 | case RuntimePlatform.WindowsPlayer: 84 | case RuntimePlatform.WindowsEditor: 85 | return perStr; 86 | case RuntimePlatform.IPhonePlayer: 87 | case RuntimePlatform.OSXPlayer: 88 | case RuntimePlatform.OSXEditor: 89 | return $"file://{perStr}"; 90 | } 91 | return perStr; 92 | } 93 | 94 | private static string persistentRootPath; 95 | /// 96 | /// 获取bundle缓存文件夹路径 97 | /// 98 | internal static string PersistentRootPath() 99 | { 100 | if (string.IsNullOrEmpty(persistentRootPath)) 101 | { 102 | var path = $"{UnityEngine.Application.persistentDataPath}/{BundleCacheDir}"; 103 | if (!Directory.Exists(path)) 104 | Directory.CreateDirectory(path); 105 | persistentRootPath = GetRegularPath(path); 106 | } 107 | return persistentRootPath; 108 | } 109 | } 110 | 111 | /// 112 | /// 下载的 缓存资源文件管理 113 | /// 114 | internal static class FxCacheHelper 115 | { 116 | /// 117 | /// 清除缓存资源 118 | /// 119 | internal static void ClearBundleCache() 120 | { 121 | var cachePath = FxPathHelper.PersistentRootPath(); 122 | if (!Directory.Exists(cachePath)) return; 123 | Directory.Delete(cachePath, true); 124 | FxDebug.Log("Clear all download cache finished!"); 125 | } 126 | 127 | /// 128 | /// 删除缓存指定文件 129 | /// 130 | /// 131 | internal static void DeleteCacheFile(string name) 132 | { 133 | var cacheFile = FxPathHelper.PersistentLoadPath(name); 134 | if (!File.Exists(cacheFile)) return; 135 | File.Delete(cacheFile); 136 | } 137 | } 138 | } -------------------------------------------------------------------------------- /FuXi/Runtime/Helper/FxHelper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4a0d5e47c9da433b98177054093312d1 3 | timeCreated: 1650941621 -------------------------------------------------------------------------------- /FuXi/Runtime/Helper/FxUtility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Security.Cryptography; 4 | 5 | // ReSharper disable once CheckNamespace 6 | namespace FuXi 7 | { 8 | internal static class FxUtility 9 | { 10 | private static readonly double[] byteUnits = 11 | { 12 | 1073741824.0, 1048576.0, 1024.0, 1 13 | }; 14 | 15 | private static readonly string[] byteUnitsNames = 16 | { 17 | "GB", "MB", "KB", "B" 18 | }; 19 | 20 | internal static string FormatBytes(long bytes) 21 | { 22 | var size = "0 B"; 23 | if (bytes == 0) return size; 24 | 25 | for (var index = 0; index < byteUnits.Length; index++) 26 | { 27 | var unit = byteUnits[index]; 28 | if (bytes >= unit) 29 | { 30 | size = $"{bytes / unit:##.##} {byteUnitsNames[index]}"; 31 | break; 32 | } 33 | } 34 | return size; 35 | } 36 | 37 | internal static Tuple FormatByteTuple(long bytes) 38 | { 39 | var size = new Tuple("0", "B"); 40 | if (bytes == 0) return size; 41 | for (var index = 0; index < byteUnits.Length; index++) 42 | { 43 | var unit = byteUnits[index]; 44 | if (bytes >= unit) 45 | { 46 | size = new Tuple($"{bytes / unit:##.##}", $"{byteUnitsNames[index]}"); 47 | break; 48 | } 49 | } 50 | return size; 51 | } 52 | 53 | internal static string FileName(string path) 54 | { 55 | path = path.Replace("\\", "/"); 56 | if (path.Contains("/")) 57 | { 58 | var lastIndex = path.LastIndexOf('/'); 59 | path = path.Substring(lastIndex + 1, path.Length - lastIndex - 1); 60 | } 61 | if (path.Contains(".")) 62 | { 63 | var lastIndex = path.LastIndexOf('.'); 64 | path = path.Substring(0, lastIndex); 65 | } 66 | return path; 67 | } 68 | 69 | public static long FileSize(string file) 70 | { 71 | FileInfo fileInfo = new FileInfo(file); 72 | return fileInfo.Length; 73 | } 74 | 75 | public static string FileMd5(string file) 76 | { 77 | try 78 | { 79 | using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read)) 80 | { 81 | MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider(); 82 | var hashBytes = md5.ComputeHash(fs); 83 | return Bytes2String(hashBytes); 84 | } 85 | } 86 | catch (Exception e) 87 | { 88 | FxDebug.LogError($"read file:{file} md5 failure with error:{e.Message}"); 89 | return string.Empty; 90 | } 91 | } 92 | 93 | public static string FileCrc32(string file) 94 | { 95 | try 96 | { 97 | using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read)) 98 | { 99 | Crc32Algorithm crc32 = new Crc32Algorithm(); 100 | var hashBytes = crc32.ComputeHash(fs); 101 | return Bytes2String(hashBytes); 102 | } 103 | } 104 | catch (Exception e) 105 | { 106 | FxDebug.LogError($"read file:{file} crc32 failure with error:{e.Message}"); 107 | return string.Empty; 108 | } 109 | } 110 | 111 | private static string Bytes2String(byte[] hashBytes) 112 | { 113 | string res = BitConverter.ToString(hashBytes); 114 | res = res.Replace("-", ""); 115 | return res.ToLower(); 116 | } 117 | } 118 | } -------------------------------------------------------------------------------- /FuXi/Runtime/Helper/FxUtility.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e5c753ab2b214159af4e89c1e2f26529 3 | timeCreated: 1650941646 -------------------------------------------------------------------------------- /FuXi/Runtime/Manifest.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f14ff60a4e7f473784ee3feca0bbb337 3 | timeCreated: 1653904792 -------------------------------------------------------------------------------- /FuXi/Runtime/Manifest/FxManifest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | // ReSharper disable once CheckNamespace 6 | namespace FuXi 7 | { 8 | [Serializable] 9 | public class FxManifest 10 | { 11 | //资源版本号 12 | public int ResVersion; 13 | //APP版本号 14 | public string AppVersion; 15 | //加密算法 16 | public string EncryptType; 17 | //资源根路径 18 | public string RootPath; 19 | //是否开启断点续传 20 | public bool OpenBreakResume; 21 | 22 | public AssetManifest[] Assets; 23 | public BundleManifest[] Bundles; 24 | public PackageManifest[] Packages; 25 | 26 | internal readonly Dictionary Path2AssetManifest = new Dictionary(); 27 | internal readonly Dictionary Name2BundleManifest = new Dictionary(); 28 | internal readonly Dictionary Name2PackageManifest = new Dictionary(); 29 | internal static FxManifest Parse(string jsonContent) 30 | { 31 | if (string.IsNullOrEmpty(jsonContent)) 32 | { 33 | FxDebug.LogError("manifest json content is null or empty!"); 34 | return null; 35 | } 36 | try 37 | { 38 | var manifest = JsonUtility.FromJson(jsonContent); 39 | foreach (var asManifest in manifest.Assets) manifest.Path2AssetManifest.Add(asManifest.Path, asManifest); 40 | foreach (var bdManifest in manifest.Bundles) manifest.Name2BundleManifest.Add(bdManifest.BundleHashName, bdManifest); 41 | foreach (var pManifest in manifest.Packages) manifest.Name2PackageManifest.Add(pManifest.PackageName, pManifest); 42 | return manifest; 43 | } 44 | catch (Exception e) 45 | { 46 | throw new Exception(e.Message); 47 | } 48 | } 49 | } 50 | 51 | /// 52 | /// 资产信息 53 | /// 54 | [Serializable] 55 | public struct AssetManifest 56 | { 57 | /// 58 | /// 资产路径 59 | /// 60 | public string Path; 61 | /// 62 | /// 是否是原生资产 63 | /// 64 | public bool IsRawFile; 65 | /// 66 | /// 资产所属Bundle ID 67 | /// 68 | public int HoldBundle; 69 | /// 70 | /// 资产依赖Bundle ID 71 | /// 72 | public int[] DependBundles; 73 | } 74 | 75 | /// 76 | /// 分包信息 DLC 77 | /// 78 | [Serializable] 79 | public struct PackageManifest 80 | { 81 | /// 82 | /// 分包名称 83 | /// 84 | public string PackageName; 85 | /// 86 | /// 分包包含的Bundle ID 只包含独有资源Bundle, 如果有依赖共享的则在公共部分 87 | /// 88 | public int[] Bundles; 89 | /// 90 | /// 是否是内置DLC 91 | /// 92 | public bool IsBuiltin; 93 | } 94 | 95 | /// 96 | /// AB 包 信息 97 | /// 98 | [Serializable] 99 | public struct BundleManifest 100 | { 101 | public string BundleHashName; 102 | public string CRC; 103 | public string Hash; 104 | public bool IsBuiltin; 105 | public long Size; 106 | } 107 | } -------------------------------------------------------------------------------- /FuXi/Runtime/Manifest/FxManifest.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4783fa292103416e9eb3ea193a91e7ac 3 | timeCreated: 1650613499 -------------------------------------------------------------------------------- /FuXi/Runtime/Manifest/FxManifestDriver.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1b5d15d4a1094024899061f6557b560a 3 | timeCreated: 1653904842 -------------------------------------------------------------------------------- /FuXi/Runtime/RuntimeMode.cs: -------------------------------------------------------------------------------- 1 | // ReSharper disable once CheckNamespace 2 | namespace FuXi 3 | { 4 | /// 5 | /// 运行模式, 仅供编辑器下使用, 打包后 需要走ab包流程 6 | /// 7 | public enum RuntimeMode 8 | { 9 | /// 10 | /// 纯编辑器模式 11 | /// 12 | Editor, 13 | /// 14 | /// 离线AB模式 15 | /// 16 | Offline, 17 | /// 18 | /// 热更新模式 19 | /// 20 | Runtime, 21 | } 22 | } -------------------------------------------------------------------------------- /FuXi/Runtime/RuntimeMode.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2559394ee4ce459b832604c71fcc3d2d 3 | timeCreated: 1651833617 -------------------------------------------------------------------------------- /FuXi/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.tendo.fuxi", 3 | "displayName": "FuXi", 4 | "description": "简单高效的资源热更新解决方案!", 5 | "version": "1.2.9", 6 | "unity": "2019.4", 7 | "license": "MIT", 8 | "changelogUrl": "https://github.com/mistletoeKANO/fuxi/blob/main/FuXi/CHANGELOG.md", 9 | "author": { 10 | "name": "Cool Developer", 11 | "url": "https://github.com/mistletoeKANO" 12 | }, 13 | "dependencies": {} 14 | } 15 | -------------------------------------------------------------------------------- /FuXi/package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7f5caefeb7d543e45bbc03dab62bcade 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 伏羲 (FuXi) 2 | 3 | [![License](https://img.shields.io/github/license/mistletoeKANO/fuxi)]([https://github.com/mistletoeKANO/fuxi/blob/master/LICENSE](https://github.com/mistletoeKANO/fuxi/blob/main/LICENSE))[![openupm](https://img.shields.io/npm/v/com.tendo.fuxi?label=openupm®istry_uri=https://package.openupm.com)](https://openupm.cn/packages/com.tendo.fuxi/) 4 | 5 | ### **版本资源 管理 工具** 6 | 7 | ## 功能 8 | 1.操作简单易上手, 单配置文件, 可添加多个配置 管理不同平台, 方便管理 9 | 10 | 2.一键 打包, 自动分析冗余 11 | 12 | 3.支持 分包, 配置方便, 分包下载方便 13 | 14 | 4.支持 同步 异步加载资源 15 | 16 | 5.内置 加密, 另提供 加密拓展接口 17 | 18 | 6.支持全量更新 和 分包更新, 多线程下载, 断点续传, 支持边玩边下载 19 | 20 | 7.支持 资源 引用 动态 分析 21 | 22 | ## 配置截图 23 | 24 | 1.项目资源配置, 热更 动态加载 资源列表 25 | 26 | ![asset](https://user-images.githubusercontent.com/33541704/173237430-d204dbb2-2ff6-441b-b28b-126b09cf3ce5.png) 27 | 28 | 2.分包配置, 分包下载 每个 分包 包含的资源列表 29 | 30 | ![package](https://user-images.githubusercontent.com/33541704/173237445-e6782f72-926e-4f22-b5fc-c6271f25099f.png) 31 | 32 | 3.设置, 配置 内置 包, 打包 加密 相关配置 33 | 34 | ![setting](https://user-images.githubusercontent.com/33541704/173237455-789474a5-58a4-40b7-af7e-7df389052b35.png) 35 | 36 | ## 资源引用动态分析工具 截图 37 | 38 | 1. Bundle引用分析截图 39 | 40 | ![Bundle引用分析](https://user-images.githubusercontent.com/33541704/175015909-124be746-de0c-4da0-9ba9-a9f1dcb6f0e5.png) 41 | 42 | 2. Asset引用分析截图 43 | 44 | ![Asset引用分析](https://user-images.githubusercontent.com/33541704/175016039-cfa83c2a-4e2f-4b4f-aaf3-64121d0e31be.png) 45 | 46 | ## 其它 47 | 48 | 快速开始: [StartUp](https://github.com/mistletoeKANO/fuxi/blob/main/StartUp.md) 49 | 50 | 示例工程: [FuXi_Example](https://github.com/mistletoeKANO/fuxi-example) 51 | 52 | QQ讨论群: 613889898 53 | 54 | -------------------------------------------------------------------------------- /StartUp.md: -------------------------------------------------------------------------------- 1 | ## 导入 FuXi 2 | A: 3 | 1. Open Edit/Project Settings/Package Manager 4 | 2. Add a new Scoped Registry (or edit the existing OpenUPM entry) 5 | 3. Name: FuXi 6 | 7 | URL: https://package.openupm.cn 8 | 9 | Scope(s): com.tendo.fuxi 10 | 4. Click Save (or Apply) 11 | 5. Open Window/Package Manager 12 | 6. Change Packages to My Registries 13 | 7. Install FuXi 14 | 15 | B: 或者 拷贝以下内容 到 Packages/manifest.json 16 | 17 | ```` 18 | { 19 | "scopedRegistries": [ 20 | { 21 | "name": "package.openupm.cn", 22 | "url": "https://package.openupm.cn", 23 | "scopes": [ 24 | "com.tendo.fuxi" 25 | ] 26 | } 27 | ], 28 | "dependencies": { 29 | "com.tendo.fuxi": "1.2.9" 30 | } 31 | } 32 | ```` 33 | 34 | # 简单介绍 35 | 36 | ### 新增配置, 配置参数说明 37 | 38 | 1. Project 视图 下 Create/FuXi Asset/FuXi Asset 39 | 40 | ![Snipaste_2022-06-22_21-48-23](https://user-images.githubusercontent.com/33541704/175045268-e6c5381b-d3bf-43ee-839d-7602c5f3f755.png) 41 | 42 | 3. FuXiAsset 为 主配置, 包含版本文件列表, 包含 需要 动态加载的 所有 需要热更新的 资源. 被依赖资源 可选择添加, 未添加资源 会被自动打包. 43 | 4. Builtin 为分包配置文件, 可 新增多个, 并 按照分包 接口 单独下载; 分包资产 包含的是 分包 文件 或者文件夹. 44 | 5. Settings 文件 是 相关设置, [资源根路径: 热更文件夹根路径, 打包时会被 自动剔除出 Bundle 包名, 减少包名长度], [配置所属平台: 当前配置文件 所属的 平台, 游戏运行时会根据当前设置选取对应平台配置 初始化 可加载文件列表], [加密类型: 设置加密文件类型, 默认 不加密, 可选 字节偏移加密 或者 全字节异或加密, 或者自定义加密类型]; 勾选 拷贝 全部 Bundle 到安装包 后 打包时 会自动 拷贝所有Bundle 到StreamingAssets 文件夹下; 忽略文件列表 包含 不打包的文件名后缀; [首包包含分包: 可添加 分包配置, 构建安装包时, 会拷贝 已添加分包文件 关联 Bundle 包到安装包内]. 45 | 46 | ### 配置截图说明 47 | 48 | FuXiAsset 主配置 49 | 50 | ![Snipaste_2022-06-23_14-10-22](https://user-images.githubusercontent.com/33541704/175227726-0dbb19ba-1740-45c4-bf1b-dadc990dd107.png) 51 | 52 | ### 代码启动流程 53 | 54 | 1. (**必须**) 游戏入口处 调用 启动资源管理器接口, 包含三个参数, 1: 版本管理配置文件名称(上一步新增配置文件名称: 如: FuXiAsset); 2: 资源服务器下载地址; 3: 游戏运行模式, 当前共 三种模式, 分别为 Editor 编辑器下、Offline 离线模式、RunTime 热更新 下载模式 55 | ```` 56 | await FxManager.FxLauncherAsync("FuXiAssetWindow", "http://192.168.1.2/Windows/", RuntimeMode); 57 | ```` 58 | 2. 检查 版本更新 59 | ```` 60 | await FxManager.FxCheckUpdate(f => 61 | { 62 | form.UpdateHandle(0, $"检查更新:{f}"); 63 | }); 64 | ```` 65 | 3. 获取更新 列表, 返回 DownloadInfo 包含 文件下载大小 和 文件下载列表 66 | ```` 67 | var download = await FxManager.FxCheckDownloadSize(true); 68 | ```` 69 | 4. 下载 资源 70 | ```` 71 | if (download.DownloadSize > 0) 72 | { 73 | GameDebugger.Log($"检测到版本变更, 大小:{download.FormatSize}"); 74 | await FxManager.FxCheckDownload(download, a => 75 | { 76 | form.UpdateHandle(a,$"正在下载: {a}"); 77 | }); 78 | GameDebugger.Log("下载完成!"); 79 | } 80 | ```` 81 | 82 | ## 加载资源 83 | 84 | 1. FxAsset 加载 资源, 相关接口 自行查看 85 | `` 86 | FxAsset fxAsset = await FxAsset.LoadAsync(path); 87 | `` 88 | 3. FxScene 加载 场景 89 | `` 90 | await FxScene.LoadSceneAsync(scenePath, additive); 91 | `` 92 | 5. FxRawAsset 加载 原生文件 93 | 94 | ## 注意事项 95 | 96 | 1.加密方式为 XOR 时,不支持内置Bundle文件到安装包内, 主要是XOR加密方式需以文件流形式读取解密, StreamingAssets文件夹 不支持相关操作! 如需 XOR 加密, Bundle 文件需先下载 后使用. 97 | 98 | 2.异步加载资源才支持边玩边下载, XOR 加密 情况下 需要 异步加载, 从服务器 下载到 读写区 进行解密加载(因此首包不应包含额外资产, 否则使用 OFFSET 加密资源). 99 | 100 | 101 | --------------------------------------------------------------------------------