├── FuXi
├── Readme.md
├── Editor
│ ├── Data.meta
│ ├── Resources
│ │ ├── Uss
│ │ │ ├── Fx_CommonInspector.uss
│ │ │ ├── Fx_BuildAsset.uss
│ │ │ ├── Fx_BuildAsset.uss.meta
│ │ │ ├── Fx_CommonInspector.uss.meta
│ │ │ ├── Fx_BundleReferenceWindow.uss.meta
│ │ │ ├── Fx_VersionManagerWindow.uss.meta
│ │ │ ├── Fx_VersionManagerWindow.uss
│ │ │ └── Fx_BundleReferenceWindow.uss
│ │ ├── Fx_ReferenceView.jpg
│ │ ├── Gizmos
│ │ │ ├── Fx_About.png
│ │ │ ├── Fx_Asset.png
│ │ │ ├── Fx_PathMenu.png
│ │ │ ├── Fx_Setting.png
│ │ │ ├── Fx_Asset Black.png
│ │ │ ├── Fx_AssetPackage.png
│ │ │ ├── Fx_About.png.meta
│ │ │ ├── Fx_Asset.png.meta
│ │ │ ├── Fx_PathMenu.png.meta
│ │ │ ├── Fx_Asset Black.png.meta
│ │ │ ├── Fx_Setting.png.meta
│ │ │ └── Fx_AssetPackage.png.meta
│ │ ├── Images
│ │ │ ├── Label_Bottom_Line.png
│ │ │ └── Label_Bottom_Line.png.meta
│ │ ├── Gizmos.meta
│ │ ├── Images.meta
│ │ ├── Uss.meta
│ │ └── Fx_ReferenceView.jpg.meta
│ ├── Helper.meta
│ ├── Inspector.meta
│ ├── Simulation.meta
│ ├── Window.meta
│ ├── AssembleInfo.cs.meta
│ ├── Fx_Command.cs.meta
│ ├── Fx_Style.cs.meta
│ ├── Fx_CreateMenu.cs.meta
│ ├── Fx_EditorConfigs.cs.meta
│ ├── BuildPipeline
│ │ ├── IBuild.cs.meta
│ │ ├── BuildBundleProcess.cs.meta
│ │ ├── BuildPlayerProcess.cs.meta
│ │ └── IBuild.cs
│ ├── Helper
│ │ ├── BuildHelper.cs.meta
│ │ ├── Fx_PlayerName.cs.meta
│ │ ├── IPlayerNameDefine.cs.meta
│ │ ├── ProcessingHelper.cs.meta
│ │ ├── DoCreateFuXiBuildAsset.cs.meta
│ │ ├── DoCreateFuXiBuildPackage.cs.meta
│ │ ├── IBuildPreprocess.cs.meta
│ │ ├── IPlayerNameDefine.cs
│ │ ├── IBuildPreprocess.cs
│ │ ├── Fx_PlayerName.cs
│ │ ├── DoCreateFuXiBuildAsset.cs
│ │ ├── DoCreateFuXiBuildPackage.cs
│ │ └── ProcessingHelper.cs
│ ├── Window
│ │ ├── Fx_AssetView.cs.meta
│ │ ├── Fx_BaseView.cs.meta
│ │ ├── Fx_BundleView.cs.meta
│ │ ├── Fx_BundleReferenceWindow.cs.meta
│ │ ├── Fx_VersionManagerWindow.cs.meta
│ │ ├── Fx_BaseView.cs
│ │ └── Fx_BundleView.cs
│ ├── Simulation
│ │ ├── FxEditorAsset.cs.meta
│ │ ├── FxEditorRawAsset.cs.meta
│ │ ├── FxEditorScene.cs.meta
│ │ ├── FxEditorRawAsset.cs
│ │ ├── FxEditorAsset.cs
│ │ └── FxEditorScene.cs
│ ├── Fx_InitializeBeforeSceneLoad.cs.meta
│ ├── Inspector
│ │ ├── Fx_BuildAssetInspector.cs.meta
│ │ ├── Fx_BuildPackageInspector.cs.meta
│ │ ├── Fx_BuildSettingInspector.cs.meta
│ │ ├── Fx_BuildPackageInspector.cs
│ │ └── Fx_BuildSettingInspector.cs
│ ├── Fx_Editor.asmdef.meta
│ ├── Resources.meta
│ ├── BuildPipeline.meta
│ ├── AssembleInfo.cs
│ ├── Data
│ │ ├── Fx_BuildPackage.cs
│ │ ├── Fx_BuildAsset.cs.meta
│ │ ├── Fx_BuildPackage.cs.meta
│ │ ├── Fx_BuildSetting.cs.meta
│ │ ├── Fx_BuildSetting.cs
│ │ └── Fx_BuildAsset.cs
│ ├── Fx_EditorConfigs.cs
│ ├── Fx_Editor.asmdef
│ ├── Fx_CreateMenu.cs
│ ├── Fx_InitializeBeforeSceneLoad.cs
│ ├── Fx_Command.cs
│ └── Fx_Style.cs
├── Runtime
│ ├── Base.meta
│ ├── Encrypt.meta
│ ├── FTask.meta
│ ├── Helper.meta
│ ├── Manifest.meta
│ ├── FTask
│ │ ├── FTask.cs.meta
│ │ ├── AsyncFTaskMethodBuilder.cs.meta
│ │ ├── AsyncMethodBuilderAttribute.cs.meta
│ │ ├── AsyncMethodBuilderAttribute.cs
│ │ ├── AsyncFTaskMethodBuilder.cs
│ │ └── FTask.cs
│ ├── FUpdateProcess.meta
│ ├── FuXiManager.cs.meta
│ ├── RuntimeMode.cs.meta
│ ├── AssembleInfo.cs.meta
│ ├── AssetPolling.cs.meta
│ ├── Base
│ │ ├── FxAsyncTask.cs.meta
│ │ ├── FxReference.cs.meta
│ │ ├── FxAsyncTask.Global.cs.meta
│ │ ├── FxReference.cs
│ │ ├── FxAsyncTask.cs
│ │ └── FxAsyncTask.Global.cs
│ ├── FDownloadProcess.meta
│ ├── Helper
│ │ ├── FxDebug.cs.meta
│ │ ├── FxHelper.cs.meta
│ │ ├── FxUtility.cs.meta
│ │ ├── Crc32Algorithm.cs.meta
│ │ ├── FxUtility.cs
│ │ ├── FxHelper.cs
│ │ └── FxDebug.cs
│ ├── Encrypt
│ │ ├── BaseEncrypt.cs.meta
│ │ ├── EncryptMode.cs.meta
│ │ ├── FxEncryptXor.cs.meta
│ │ ├── FxEncryptOffset.cs.meta
│ │ ├── EncryptMode.cs
│ │ ├── BaseEncrypt.cs
│ │ ├── FxEncryptOffset.cs
│ │ └── FxEncryptXor.cs
│ ├── Manifest
│ │ ├── FxManifest.cs.meta
│ │ ├── FxManifestDriver.cs.meta
│ │ └── FxManifest.cs
│ ├── FLoaderProcess
│ │ ├── FxAsset.cs.meta
│ │ ├── FxRawAsset.cs.meta
│ │ ├── FxScene.cs.meta
│ │ ├── BundleLoader.cs.meta
│ │ ├── FxAsset.Global.cs.meta
│ │ ├── FxScene.Global.cs.meta
│ │ ├── DependBundleLoader.cs.meta
│ │ ├── FxRawAsset.Global.cs.meta
│ │ ├── DependBundleLoader.Global.cs.meta
│ │ ├── FxRawAsset.Global.cs
│ │ ├── FxScene.Global.cs
│ │ ├── DependBundleLoader.Global.cs
│ │ ├── FxAsset.Global.cs
│ │ ├── FxScene.cs
│ │ ├── DependBundleLoader.cs
│ │ ├── FxRawAsset.cs
│ │ ├── BundleLoader.cs
│ │ └── FxAsset.cs
│ ├── FDownloadProcess
│ │ ├── Downloader.cs.meta
│ │ ├── ThreadDownloader.cs.meta
│ │ ├── Downloader.cs
│ │ └── ThreadDownloader.cs
│ ├── FUpdateProcess
│ │ ├── CheckWWWManifest.cs.meta
│ │ ├── CheckDownloadBundle.cs.meta
│ │ ├── CheckDownloadSize.cs.meta
│ │ ├── CheckLocalManifest.cs.meta
│ │ ├── CheckLocalManifest.cs
│ │ ├── CheckDownloadBundle.cs
│ │ └── CheckDownloadSize.cs
│ ├── Fx_Runtime.asmdef.meta
│ ├── FLoaderProcess.meta
│ ├── AssembleInfo.cs
│ ├── Fx_Runtime.asmdef
│ ├── RuntimeMode.cs
│ └── AssetPolling.cs
├── Bridge
│ ├── Editor
│ │ ├── EditorExtension.cs.meta
│ │ ├── ProjectBrowserExtension.cs.meta
│ │ ├── EditorInternalBridge.asmdef.meta
│ │ ├── EditorInternalBridge.asmdef
│ │ ├── EditorExtension.cs
│ │ └── ProjectBrowserExtension.cs
│ └── Editor.meta
├── CHANGELOG.md.meta
├── LICENSE.md.meta
├── Readme.md.meta
├── package.json.meta
├── Bridge.meta
├── Editor.meta
├── Runtime.meta
├── package.json
├── CHANGELOG.md
└── LICENSE.md
├── README.md
└── StartUp.md
/FuXi/Readme.md:
--------------------------------------------------------------------------------
1 | 简单高效的版本资源管理解决方案!
--------------------------------------------------------------------------------
/FuXi/Editor/Data.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 75a5721216cb4be3b88c500606106b8e
3 | timeCreated: 1649405912
--------------------------------------------------------------------------------
/FuXi/Editor/Resources/Uss/Fx_CommonInspector.uss:
--------------------------------------------------------------------------------
1 | .fx-inspector-margins{
2 | padding: 3px 2px 2px 2px;
3 | }
--------------------------------------------------------------------------------
/FuXi/Runtime/Base.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 379f0ae1ff7c4f6288cb15aef7ed505d
3 | timeCreated: 1651892954
--------------------------------------------------------------------------------
/FuXi/Editor/Helper.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 6e3538f60ad6494982319086db83210e
3 | timeCreated: 1649411367
--------------------------------------------------------------------------------
/FuXi/Editor/Inspector.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: c61259e99642458ab5eaa19ad0a514b6
3 | timeCreated: 1649405965
--------------------------------------------------------------------------------
/FuXi/Editor/Simulation.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 86d6c9d04f304c45a28f3d8191d386cf
3 | timeCreated: 1654754774
--------------------------------------------------------------------------------
/FuXi/Editor/Window.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: c364beda4a7e4eeaa9242fdb35397921
3 | timeCreated: 1649401191
--------------------------------------------------------------------------------
/FuXi/Runtime/Encrypt.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: f05fa697d3874f11abdbc97b641d4817
3 | timeCreated: 1654857949
--------------------------------------------------------------------------------
/FuXi/Runtime/FTask.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 8d3d7cfdd3654ca584b3e1cf9310a8bf
3 | timeCreated: 1657966297
--------------------------------------------------------------------------------
/FuXi/Runtime/Helper.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: f2b5f5c8c9144defb33ca41eb4e33951
3 | timeCreated: 1650941585
--------------------------------------------------------------------------------
/FuXi/Runtime/Manifest.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: f14ff60a4e7f473784ee3feca0bbb337
3 | timeCreated: 1653904792
--------------------------------------------------------------------------------
/FuXi/Editor/AssembleInfo.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 24da8f99bb0748afbdd1942897013340
3 | timeCreated: 1649407779
--------------------------------------------------------------------------------
/FuXi/Editor/Fx_Command.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 10653d47860045978fa4e47f2c0b6d80
3 | timeCreated: 1655718225
--------------------------------------------------------------------------------
/FuXi/Editor/Fx_Style.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 49b9349ece0c40318bdf69667419a3a0
3 | timeCreated: 1649402359
--------------------------------------------------------------------------------
/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/FuXiManager.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 9385d750d5f04ef3bf86011fb044c788
3 | timeCreated: 1651747285
--------------------------------------------------------------------------------
/FuXi/Runtime/RuntimeMode.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 2559394ee4ce459b832604c71fcc3d2d
3 | timeCreated: 1651833617
--------------------------------------------------------------------------------
/FuXi/Editor/Fx_CreateMenu.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 14e29eb5802e43f580a363f7b8193fd7
3 | timeCreated: 1649384213
--------------------------------------------------------------------------------
/FuXi/Editor/Fx_EditorConfigs.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 9f0798658e494889b918cf9a886b4c4a
3 | timeCreated: 1649388406
--------------------------------------------------------------------------------
/FuXi/Runtime/AssembleInfo.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: e737decd04c147ccac927bbf7add532a
3 | timeCreated: 1650784230
--------------------------------------------------------------------------------
/FuXi/Runtime/AssetPolling.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: e06399a706b649bd93c317c2e5f645c1
3 | timeCreated: 1651747158
--------------------------------------------------------------------------------
/FuXi/Runtime/Base/FxAsyncTask.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: ba828b6310d445639e3d3d25d6d97b90
3 | timeCreated: 1651821224
--------------------------------------------------------------------------------
/FuXi/Runtime/Base/FxReference.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 570e225906a3477cbb52c2e6255da313
3 | timeCreated: 1654913538
--------------------------------------------------------------------------------
/FuXi/Runtime/FDownloadProcess.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 2604c5add5fc444597e5738b00f35efa
3 | timeCreated: 1653359536
--------------------------------------------------------------------------------
/FuXi/Runtime/Helper/FxDebug.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 87d3ce6c51194e418c258a5883e889d0
3 | timeCreated: 1650613759
--------------------------------------------------------------------------------
/FuXi/Runtime/Helper/FxHelper.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 4a0d5e47c9da433b98177054093312d1
3 | timeCreated: 1650941621
--------------------------------------------------------------------------------
/FuXi/Runtime/Helper/FxUtility.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: e5c753ab2b214159af4e89c1e2f26529
3 | timeCreated: 1650941646
--------------------------------------------------------------------------------
/FuXi/Bridge/Editor/EditorExtension.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 377fd7a1015f4842a1dc5d3e24459811
3 | timeCreated: 1650615607
--------------------------------------------------------------------------------
/FuXi/Editor/BuildPipeline/IBuild.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 339d4607be8441a588c58af9e56f1eb1
3 | timeCreated: 1650873103
--------------------------------------------------------------------------------
/FuXi/Editor/Helper/BuildHelper.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: e4bd34f79b8047bb9ad61001dbbfd9e8
3 | timeCreated: 1650003363
--------------------------------------------------------------------------------
/FuXi/Editor/Helper/Fx_PlayerName.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: c429104a31144c2099281eabf20a512b
3 | timeCreated: 1660541692
--------------------------------------------------------------------------------
/FuXi/Editor/Window/Fx_AssetView.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: a8e50e7cd16b4dad985c76c9f6f11059
3 | timeCreated: 1655804656
--------------------------------------------------------------------------------
/FuXi/Editor/Window/Fx_BaseView.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: f580454e4cb24efcaf515f7bd87d3369
3 | timeCreated: 1655804696
--------------------------------------------------------------------------------
/FuXi/Editor/Window/Fx_BundleView.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: f6e466d7f53b4a26af8eed4a9f51ca06
3 | timeCreated: 1655804081
--------------------------------------------------------------------------------
/FuXi/Runtime/Encrypt/BaseEncrypt.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: bca930008c984a77baa6ec6fa3fdc7a7
3 | timeCreated: 1651133907
--------------------------------------------------------------------------------
/FuXi/Runtime/Encrypt/EncryptMode.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: e41ec2f707ff48e18c00e941f217f12e
3 | timeCreated: 1654858001
--------------------------------------------------------------------------------
/FuXi/Runtime/Encrypt/FxEncryptXor.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 76e95d0210f640849e75747f4b7c2c8f
3 | timeCreated: 1654867590
--------------------------------------------------------------------------------
/FuXi/Runtime/Helper/Crc32Algorithm.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 015be01675c34fb0b91368b263735294
3 | timeCreated: 1651053734
--------------------------------------------------------------------------------
/FuXi/Runtime/Manifest/FxManifest.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 4783fa292103416e9eb3ea193a91e7ac
3 | timeCreated: 1650613499
--------------------------------------------------------------------------------
/FuXi/Editor/Helper/IPlayerNameDefine.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 8d4c1b80065d48d2ad55dd010a1e8cf2
3 | timeCreated: 1660541358
--------------------------------------------------------------------------------
/FuXi/Editor/Helper/ProcessingHelper.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: bbc398c597154cc69a680daed45b17ce
3 | timeCreated: 1655348927
--------------------------------------------------------------------------------
/FuXi/Editor/Resources/Fx_ReferenceView.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mistletoeKANO/fuxi/HEAD/FuXi/Editor/Resources/Fx_ReferenceView.jpg
--------------------------------------------------------------------------------
/FuXi/Editor/Resources/Gizmos/Fx_About.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mistletoeKANO/fuxi/HEAD/FuXi/Editor/Resources/Gizmos/Fx_About.png
--------------------------------------------------------------------------------
/FuXi/Editor/Resources/Gizmos/Fx_Asset.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mistletoeKANO/fuxi/HEAD/FuXi/Editor/Resources/Gizmos/Fx_Asset.png
--------------------------------------------------------------------------------
/FuXi/Editor/Simulation/FxEditorAsset.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 340cdeb6c6424048ba82fa51ba263829
3 | timeCreated: 1654754794
--------------------------------------------------------------------------------
/FuXi/Editor/Simulation/FxEditorRawAsset.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 872314fcaf934fa7af28341e0640cc9d
3 | timeCreated: 1654945099
--------------------------------------------------------------------------------
/FuXi/Editor/Simulation/FxEditorScene.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: d5b9060b495e46b88add5eb9a3e6f4fd
3 | timeCreated: 1654755995
--------------------------------------------------------------------------------
/FuXi/Runtime/Base/FxAsyncTask.Global.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: d7ccc23bc6e5403abc44f5236f5f5452
3 | timeCreated: 1653448331
--------------------------------------------------------------------------------
/FuXi/Runtime/Encrypt/FxEncryptOffset.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 169e342ec6c244d298a2369d7b1d8463
3 | timeCreated: 1651141270
--------------------------------------------------------------------------------
/FuXi/Runtime/FLoaderProcess/FxAsset.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: b04bf5b57e4441c8985a181f938e9a3d
3 | timeCreated: 1654678241
--------------------------------------------------------------------------------
/FuXi/Runtime/FLoaderProcess/FxRawAsset.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: e5e165ff90924e9183f7e38d5c83e4a1
3 | timeCreated: 1654934492
--------------------------------------------------------------------------------
/FuXi/Runtime/FLoaderProcess/FxScene.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: bca963abd1454dd19fccb7084a7b63bc
3 | timeCreated: 1654742503
--------------------------------------------------------------------------------
/FuXi/Runtime/Manifest/FxManifestDriver.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 1b5d15d4a1094024899061f6557b560a
3 | timeCreated: 1653904842
--------------------------------------------------------------------------------
/FuXi/Bridge/Editor/ProjectBrowserExtension.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: adecaf960768478391be11af754f708b
3 | timeCreated: 1649928399
--------------------------------------------------------------------------------
/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/Fx_InitializeBeforeSceneLoad.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 8bf182a033ab43db91e3599364ba92af
3 | timeCreated: 1653387687
--------------------------------------------------------------------------------
/FuXi/Editor/Helper/DoCreateFuXiBuildAsset.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 68ac5f8ca5874fbbafb330f46fdd097e
3 | timeCreated: 1649397603
--------------------------------------------------------------------------------
/FuXi/Editor/Helper/DoCreateFuXiBuildPackage.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 88ed169ffff94f66a99c8d93359b18be
3 | timeCreated: 1649409896
--------------------------------------------------------------------------------
/FuXi/Editor/Inspector/Fx_BuildAssetInspector.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: cd923e3efaf045deb86ac15cfe3ceb13
3 | timeCreated: 1649406023
--------------------------------------------------------------------------------
/FuXi/Editor/Resources/Gizmos/Fx_PathMenu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mistletoeKANO/fuxi/HEAD/FuXi/Editor/Resources/Gizmos/Fx_PathMenu.png
--------------------------------------------------------------------------------
/FuXi/Editor/Resources/Gizmos/Fx_Setting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mistletoeKANO/fuxi/HEAD/FuXi/Editor/Resources/Gizmos/Fx_Setting.png
--------------------------------------------------------------------------------
/FuXi/Editor/Window/Fx_BundleReferenceWindow.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 2477c3d052b64a4697dcf3d2e5e79c5c
3 | timeCreated: 1655777885
--------------------------------------------------------------------------------
/FuXi/Editor/Window/Fx_VersionManagerWindow.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: f885736d08f54deb839998c2ae01326c
3 | timeCreated: 1655967561
--------------------------------------------------------------------------------
/FuXi/Runtime/FDownloadProcess/Downloader.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 48a7332cc79b4512b7dfeaa349e329b6
3 | timeCreated: 1654506728
--------------------------------------------------------------------------------
/FuXi/Runtime/FLoaderProcess/BundleLoader.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 36e7eb32cf784704a1794f5bd461b488
3 | timeCreated: 1654681417
--------------------------------------------------------------------------------
/FuXi/Runtime/FLoaderProcess/FxAsset.Global.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: e84457a1f9ae4cb0b978588247c65274
3 | timeCreated: 1654678293
--------------------------------------------------------------------------------
/FuXi/Runtime/FLoaderProcess/FxScene.Global.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: a4dbb4a471034891bbf0516fdd3fd427
3 | timeCreated: 1654742529
--------------------------------------------------------------------------------
/FuXi/Runtime/FTask/AsyncFTaskMethodBuilder.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 6d0580e9cdb24d95a84cff64f9b439d1
3 | timeCreated: 1657970834
--------------------------------------------------------------------------------
/FuXi/Runtime/FUpdateProcess/CheckWWWManifest.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 49ecf0ff705d493ab82d00c8aa4e91d0
3 | timeCreated: 1653289978
--------------------------------------------------------------------------------
/FuXi/Editor/Inspector/Fx_BuildPackageInspector.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: c5b7277316a64b968922efaa337abdd9
3 | timeCreated: 1649406218
--------------------------------------------------------------------------------
/FuXi/Editor/Inspector/Fx_BuildSettingInspector.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: a0d518859ae042669bc33d6ae8da4432
3 | timeCreated: 1649406161
--------------------------------------------------------------------------------
/FuXi/Editor/Resources/Gizmos/Fx_Asset Black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mistletoeKANO/fuxi/HEAD/FuXi/Editor/Resources/Gizmos/Fx_Asset Black.png
--------------------------------------------------------------------------------
/FuXi/Runtime/FDownloadProcess/ThreadDownloader.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 5048b8dcd597454b94e8aded91085cfe
3 | timeCreated: 1654512219
--------------------------------------------------------------------------------
/FuXi/Runtime/FLoaderProcess/DependBundleLoader.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: e6491fa403da4ea2ab5e64cac1ce515c
3 | timeCreated: 1654683606
--------------------------------------------------------------------------------
/FuXi/Runtime/FLoaderProcess/FxRawAsset.Global.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: d28e75ed310c4289b84881dc83576ffc
3 | timeCreated: 1654934517
--------------------------------------------------------------------------------
/FuXi/Runtime/FTask/AsyncMethodBuilderAttribute.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: ac163044893f4ed8b9397bd757ee72c0
3 | timeCreated: 1657970789
--------------------------------------------------------------------------------
/FuXi/Runtime/FUpdateProcess/CheckDownloadBundle.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: c446d486a2b54c71aa9054d0a3bd1705
3 | timeCreated: 1654141136
--------------------------------------------------------------------------------
/FuXi/Runtime/FUpdateProcess/CheckDownloadSize.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: eb7434524d264ba5821d29e62d0381aa
3 | timeCreated: 1654141200
--------------------------------------------------------------------------------
/FuXi/Runtime/FUpdateProcess/CheckLocalManifest.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 2e7b3a093c5f446cbcdc79867b929971
3 | timeCreated: 1653289946
--------------------------------------------------------------------------------
/FuXi/Editor/Resources/Gizmos/Fx_AssetPackage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mistletoeKANO/fuxi/HEAD/FuXi/Editor/Resources/Gizmos/Fx_AssetPackage.png
--------------------------------------------------------------------------------
/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/Runtime/FLoaderProcess/DependBundleLoader.Global.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: c372c27431ad4412bc24efecdb173afe
3 | timeCreated: 1654919366
--------------------------------------------------------------------------------
/FuXi/Editor/Resources/Images/Label_Bottom_Line.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mistletoeKANO/fuxi/HEAD/FuXi/Editor/Resources/Images/Label_Bottom_Line.png
--------------------------------------------------------------------------------
/FuXi/CHANGELOG.md.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 68c79f5f40ceb8a448e4e46a4e709dc5
3 | TextScriptImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/FuXi/LICENSE.md.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: fd767ed8296c12e48ac5d153b66fc946
3 | TextScriptImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/FuXi/Readme.md.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 467065e5f20f01046914777d5d6468d9
3 | TextScriptImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/FuXi/package.json.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 7f5caefeb7d543e45bbc03dab62bcade
3 | TextScriptImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/FuXi/Bridge.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 23edbd3541d7432391a84b8fb3985344
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/FuXi/Editor.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: ccf667414652485438da1c02a86fd5a6
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/FuXi/Runtime.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 593457e6b392ca042814b4b951bb961e
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/Editor/Fx_Editor.asmdef.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 4747d22a2b65fba4c98b2588acf70724
3 | AssemblyDefinitionImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/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/Runtime/Fx_Runtime.asmdef.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 1c64a098c7bf73e4ba2651fb3807a7f4
3 | AssemblyDefinitionImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/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/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/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/Uss.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 7f048ac1d2fa6d74db51ea72118b1655
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/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/Bridge/Editor/EditorInternalBridge.asmdef.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 3cb8e2b64ae58f7489b88bc90a7703b9
3 | AssemblyDefinitionImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/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/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/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/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/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/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/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/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.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.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/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_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_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_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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 伏羲 (FuXi)
2 |
3 | []([https://github.com/mistletoeKANO/fuxi/blob/master/LICENSE](https://github.com/mistletoeKANO/fuxi/blob/main/LICENSE))[](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 | 
27 |
28 | 2.分包配置, 分包下载 每个 分包 包含的资源列表
29 |
30 | 
31 |
32 | 3.设置, 配置 内置 包, 打包 加密 相关配置
33 |
34 | 
35 |
36 | ## 资源引用动态分析工具 截图
37 |
38 | 1. Bundle引用分析截图
39 |
40 | 
41 |
42 | 2. Asset引用分析截图
43 |
44 | 
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 |
--------------------------------------------------------------------------------
/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/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/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/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/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/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/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/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/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/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/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/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/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 | }
--------------------------------------------------------------------------------
/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 | 
41 |
42 | 3. FuXiAsset 为 主配置, 包含版本文件列表, 包含 需要 动态加载的 所有 需要热更新的 资源. 被依赖资源 可选择添加, 未添加资源 会被自动打包.
43 | 4. Builtin 为分包配置文件, 可 新增多个, 并 按照分包 接口 单独下载; 分包资产 包含的是 分包 文件 或者文件夹.
44 | 5. Settings 文件 是 相关设置, [资源根路径: 热更文件夹根路径, 打包时会被 自动剔除出 Bundle 包名, 减少包名长度], [配置所属平台: 当前配置文件 所属的 平台, 游戏运行时会根据当前设置选取对应平台配置 初始化 可加载文件列表], [加密类型: 设置加密文件类型, 默认 不加密, 可选 字节偏移加密 或者 全字节异或加密, 或者自定义加密类型]; 勾选 拷贝 全部 Bundle 到安装包 后 打包时 会自动 拷贝所有Bundle 到StreamingAssets 文件夹下; 忽略文件列表 包含 不打包的文件名后缀; [首包包含分包: 可添加 分包配置, 构建安装包时, 会拷贝 已添加分包文件 关联 Bundle 包到安装包内].
45 |
46 | ### 配置截图说明
47 |
48 | FuXiAsset 主配置
49 |
50 | 
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 |
--------------------------------------------------------------------------------
/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.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_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_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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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 | }
--------------------------------------------------------------------------------