# FusionFrameworks **Repository Path**: yajink/FusionFrameworks ## Basic Information - **Project Name**: FusionFrameworks - **Description**: Unity Frameworks - **Primary Language**: C# - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2022-12-05 - **Last Updated**: 2025-09-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: Unity, Csharp, Framework ## README # FusionFrameworks Unity客户端框架,包含资源管理、音频管理、场景管理、UI管理、Excel工具、打包工具、热更新、网络等。 ## 使用插件 1. Protobuf v23.3 2. ILRuntime 2.1.0 3. EPPlus ## 安装 1. **Window -> Package Manager -> + -> Add package from git URL...** 2. 输入`https://gitee.com/yajink/FusionFrameworks.git?path=Assets/[模块包名]#v[MAJOR.MINOR.PATCH]`, 点击Add > [模块包名] > 1. com.fusion.utilities 工具模块(*必选) > 2. com.fusion.async 异步处理模块(*必选) > 3. com.fusion.frameworks 主框架(*必选) > * com.fusion.protobuf Protobuf模块(可选) > * com.fusion.net 网络模块(可选) > * com.fusion.hotfix 热更模块(可选)由于热更模块中已经对网络模块做了配置,因此需要先导入网络模块。 ## 实例 ### 测试工程 https://gitee.com/yajink/fusion-test ### 游戏示例 https://gitee.com/yajink/cyber-zero ## 文档 ### 一、资源管理 #### 资源路径 所有需要打包为AssetBundle(以下简称AB)的资源都需要存放在 **Assets/GameAssets/[xxx]** 文件夹下,可以根据自己的习惯为不同的资源划分多个子文件夹,但根目录必须创建一个 **BuildSetting** 配置文件,并且GameAssets下不能放资源。 > BuildSetting 可以通过 **Assets/Create/FusionConfig/Build Setting** 来创建 ***注意:相同目录下资源不能重名,后缀名不同也不行。例如:a.jpg 和 a.mat 不能存放在相同文件夹中。** * **BuildSetting参数说明** | 参数 | 说明 | | :---: | --- | | Build Mode | *打包模式*
1. Debug 调试版本
2. Release 正式版本 | | Compress Type | *压缩方式*
1. LZMA
2. Uncompress 不压缩
3. LZ4 | | Build Target Type | *平台*
1. Use Current Target 使用当前平台
2. Android
3. Standalone Windows
4. Standalone Windows 64
* 暂时不支持其他平台 | | Init Scene | *初始场景*
初始场景文件会由Unity打入单独的AssetBundle中,因此不需要放在GameAssets下 | | Version | *版本号*
在打完AssetBundle后,会与老版本的资源进行对比,若Large Middle Small相同,并且Resource大于老版本,就会生成一个对应老版本的Patch文件用于热更新 | #### 资源AssetBundle名称规则 AB名称会在打AssetBundle时自动设置。 为某个资源设置AB名称时,会在当前文件夹中查找 **BuildProperty** 配置文件,若找不到,则递归寻找父文件夹。 若到GameAssets文件夹还未找到,则使用默认 **BuildProperty** 配置。 > BuildProperty 可以通过 **Assets/Create/FusionConfig/Build Property** 来创建 * **BuildProperty参数说明** | 参数 | 说明 | | :---: | --- | | Type | *AB命名方式*
1. None 名称为null
2. File 用文件名命名
3. Folder 用所在文件夹名称命名 | | Compress *Type* | *压缩方式*
* 若压缩方式与Build Setting配置不同,则该资源不会被记录在依赖资源文件中,只能作为主要资源加载
1. LZMA
2. Uncompress 不压缩
3. LZ4
4. Use Build Setting 使用Build Setting中的压缩方式 | 若需要将Sprite打入图集,可以通过 **AtlasProperty** 配置文件,该配置文件的查找方式与 **BuildProperty** 相同。 只会将符合配置条件的Sprite打入图集,其余资源还是按照 **BuildProperty** 来设置。 > AtlasProperty 可以通过 **Assets/Create/FusionConfig/Atlas Property** 来创建 * **AtlasProperty参数说明** | 参数 | 说明 | | :---: | --- | | Pack Unit | *图集粒度*
0 文件夹中所有符合条件的Sprite打入一张图集
-1 不打图集
[n] 符合条件的n张Sprite打入一张图集 | | Ignore Size | *过滤Sprite分辨率*
X Sprite的宽
Y Sprite的高
大于这个分辨率的Sprite不会被打入图集 | #### AssetBundle打包 将资源放入指定文件夹并且完成上述配置后,就可以通过 **Build/BuildAssets** 菜单选项进行打包。AssetBundle会被入 **StreamingAssets/ManagedAssets** 文件夹中。 可以在 **项目根目录/FusionTemp** 文件夹下找到当前版本的资源、老版本资源MD5以及热更Patchs等。 * **打包选项** | 操作 | 说明 | | :---: | --- | | **Build/BuildAssets** | 打AssetsBundle | | **Build/BuildPlayer** | 直接打可执行文件 | | **Build/BuildDynamic** | 打出热更文件 | | **Build/Build** | 打AssetsBundle,并且打出可执行文件 | | **AssetsManager/ClearAssetBundleName** | 清除AssetBundle名称 | | **AssetsManager/CopyAssetsToStreamingAssets** | 将FusionTemp下的资源拷贝到StreamingAssets下 | | **AssetsManager/SwichEditorAssetLoadType** | 切换Editor下资源加载方式
AssetBundle
AssetDatabase | | **AssetsManager/Build** | 打AssetsBundle,但不会拷贝到StreamingAssets下 | #### 资源加载与销毁 可以通过 **AssetsManager** 或 **AssetsUtility** 来对资源进行加载和销毁。 > 资源应的AssetBundle拥有两个引用值:**非持久引用**、**持久引用**。 > 当调用资源加载方法时,其对应的AssetBundle的引用值(persistentAsset=false为**非持久引用**,true为**持久引用**)会加1。 > 当调用资源销毁方法时,其对应的AssetBundle的引用值(persistentAsset=false为**非持久引用**,true为**持久引用**)会减1。 > 当AssetBundle **非持久引用** 和 **持久引用** 和(后续使用引用值表示它们的和)为0时,AssetBundle会被销毁。 > 切换场景时,**非持久引用** 会被清零。 > 默认加载资源引用是 **非持久引用**。 * **同步加载** ```c# Sprite sprite = AssetsManager.Instance.Load("Sprites/hearts"); ``` > persistentAsset 传入 true,可将资源标记为持久资源。 * **异步加载资源** ```c# AssetsManager.Instance.LoadAsync("Sprites/hearts", delegate (Sprite sprite) { //在回调中对加载的资源进行处理 }); ``` > persistentAsset 传入 true,可将资源标记为持久资源。 * **资源销毁资源** ```c# AssetsUtility.Release("Sprites/hearts"); ``` > 引用值为0时,为防止AssetBundle销毁后又立刻被加载,会有一个5秒的延迟。 > persistentAsset 传入 true,可销毁持久资源。 ```c# AssetsUtility.ReleaseImmediate("Sprites/hearts"); ``` > 引用值为0时,AssetBundle立刻被销毁。 > persistentAsset 传入 true,可销毁持久资源。 * **同步加载预制体** ```c# GameObject go = AssetsUtility.CreateGameObject("Prefabs/Cube"); ``` * **异步加载预制体** ```c# AssetsUtility.CreateGameObjectAsync("Prefabs/Cube", finishCallback: delegate (GameObject go) { //在回调中可以处理加载的对象 }); ``` * **销毁预制体** ```c# AssetsUtility.Release(go); ``` > 引用值为0时,为防止AssetBundle销毁后又立刻被加载,会有一个5秒的延迟。 ```c# AssetsUtility.ReleaseImmediate(go); ``` > 引用值为0时,AssetBundle立刻被销毁。 * **其他资源操作** ```c# AssetsUtility.SetSpriteOfImage(gameObject, "Sprites/hearts"); ``` > 为Image设置图片。 > 当Image对象或父对象被销毁时,资源对应的AssetBundle的非持久引用会减去1。 ```c# AssetsUtility.SetAudioSourceClip(audioSource, "Audios/1"); ``` > 为AudioSource设置图片。 > 当AudioSource对象或父对象被销毁时,资源对应的AssetBundle的非持久引用会减去1。 ### 二、音频管理 音频播放需要 **AudioPlayer** 对象 #### 音频操作 ```c# AudioPlayer audioPlayer = new AudioPlayer(); ``` > 构造方法中可传入gameObject,这样可以让AudioPlayer变为3D播放。 > 构造方法中可传入persistent,标记该音频播放器是持久的。持久音频切换场景不会被销毁,只有在切换音频时,会将上一个音频销毁。 * **淡入淡出** ```c# audioPlayer.FadeInSetter(1.0f); audioPlayer.FadeOutSetter(1.0f); ``` > duration 淡入淡出的时间 * **循环** ```c# audioPlayer.LoopSetter(true); ``` * **音量** ```c# audioPlayer.VolumeSetter(0.5f); ``` > 参数为[0.0, 1.0] 区间的浮点数 * **播放** ```c# audioPlayer.Play("Audios/1"); ``` * **停止** ```c# audioPlayer.Stop(); ``` * **暂停** ```c# audioPlayer.Pause(); ``` * **销毁** ```c# audioPlayer.Release(); ``` #### 音频标签 为音频播放器设置标签,可以批量修改某个标签下的所有音频播放器的参数。 * **设置标签** ```c# audioPlayer.TagSetter("BGM"); ``` * **设置标签音量** ```c# AudioManager.Instance.SetTagVolume("BGM", 0.5f); ``` ### 三、场景管理 #### 场景加载 * **同步加载** ```c# ScenesManager.Instance.Load("Scenes/First"); ``` > LoadSceneMode.Single 加载单个场景 LoadSceneMode.Additive 额外场景 > clearFlag 是否清理资源 * **异步加载** ```c# ScenesManager.Instance.LoadAsync("Scenes/First"); ``` > LoadSceneMode.Single 加载单个场景 LoadSceneMode.Additive 额外场景 > startCallback 回调方法参数为 AsyncOperation > finishCallback 加载结束回调 > clearFlag 是否清理资源 #### 异步加载任务 异步加载任务是通过LoadAsyncTask类来加载场景,这种加载方式可以加载一个Single场景和多个Addtion场景并且自动合并Single与Addition的加载进度。除此之外,还提供了场景数据的保存于加载功能。 * **创建LoadAsyncTask** ```c# ScenesManager.LoadAsyncTask loadAsyncTask = new ScenesManager.LoadAsyncTask("Scenes/First"); ``` * **添加额外场景** ```c# loadAsyncTask.AddAdditive("Scenes/Second"); ``` * **回调方法** ```c# loadAsyncTask.updateCallback = delegate (float progress) { //在此处理进度变更逻辑 }; ``` ```c# loadAsyncTask.finishCallback = delegate () { //在此处理加载完成逻辑 }; ``` * **添加额外场景** ```c# loadAsyncTask.AddAdditive("Scenes/Second"); ``` * **添加场景数据处理器** ```c# loadAsyncTask.AddSceneDataHandler(new SceneUIHandler()); ``` > SceneUIHandler 可以保存旧场景的UI栈。 > 当从场景A跳转到场景B时,SceneUIHandler会保存场景A的UI栈。下一次跳转回场景A时,会自动加载SceneUIHandler中的UI栈。 > > 自定义SceneHandler > * 新建一个类,实现SceneDataHandler接口。 > * 在接口Save中写保存数据的逻辑。 > * 在Load中写加载数据的逻辑。 * **开始异步任务** ```c# ScenesManager.LoadAsyncOperation loadAsyncOperation = loadAsyncTask.Schedule(); ``` > loadAsyncOperation 中也可以获取到进度Progress,以及是否完成IsDone。 ### 四、UI管理 使用UI管理功能之前,需要将Prefab **Packages/com.fusion.frameworks/Runtime/Prefabs/UI/UI** 拖入初始场景中。 **可以修改UI Prefab的属性,但不能更改子节点的层级关系。** **UI支持热更,详情在热更部分** #### 创建UI页面 一个UI Prefab需要对应一个UI脚本。 UI Prefab所在的相对路径就是创建UI页面的路径。 UI脚本的命名空间+类名,必须与UI Prefab路径对应。 以 **Prefabs/UI/Page1** 为例: ```c# using Fusion.Frameworks.UI; namespace Prefabs.UI { public class Page1 : UIObject { public Page1() { } public Page1(UIData data) : base(data) { } public override void Init() { base.Init(); } public override void Update() { base.Update(); } public override void OnFinished() { base.OnFinished(); } public override void OnDestroy() { base.OnDestroy(); } } } ``` > 必须有一个默认构造函数,反射需要调用。 > 生命周期函数 > Init 仅在UI创建的时候执行一次。 > Update 创建UI时,会执行一次Update。当UI对象的updateLastUI属性为true时,Finish会自动调用上一个页面的Update方法进行页面更新。 > OnFinished 当调用UI的Finish方法时,会触发此回调。 > OnDestroy 当页面被销毁时,会触发此回调。 * **同步创建UI** ```c# UIManager.Instance.Launch("Prefabs/UI/Page1"); ``` > * **异步创建UI** ```c# UIManager.Instance.LaunchAsync("Prefabs/UI/Page1"); ``` #### 数据传递 向UI页面传递数据,需要一个数据类。 这个类继承自UIData ```c# public class PageData : UIData { // 可以添加自定义的变量,例如下面的text变量。 public string text; } ``` ```c# PageData pageData = new PageData(); pageData.text = "Passed Value"; UIManager.Instance.LaunchAsync("Prefabs/UI/Page1", pageData); ``` 可以在UI脚本的有参构造方法中初始化数据 ```c# PageData pageData; public Page1(UIData data) : base(data) { pageData = (PageData)data; } ``` #### 控件设置 在 **Init** 方法中获取控件。 ```c# TextMeshProUGUI text; Image image; Button jumpToBtn; Button closeBtn; public override void Init() { base.Init(); text = Utility.Find(gameObject, "Text"); image = Utility.Find(gameObject, "Image"); jumpToBtn = Utility.Find