Unity Addressables 简易加载应用(三)

AddressableAssetSettings设置

首先我们需要设置一下构建后数据的存放位置,打开前文所述的Addressables Profiles 进行设置,这里仅修改默认配置Default 中的Remote 项,当然你也可以通过左上方Create 创建新的配置修改和选择(别忘了修改Profile In Use 选择哟),下拉列表选中自定义,修改RemoteLoadPath (远程加载地址)与RemoteBuildPath (远程构建存放地址),保持地址一致,最好使用绝对路径方便测试。

这里需要勾选Build Remote Catalog ,将Build&Load Paths 选中Remote ,这里的Remote 其实就是刚刚配置Default 中的Remote 项地址。该项其实就是创建远程缓存数据,需要勾选确认创建,并选择地址存放和加载。最下方Only update catalogs manually 取消勾选,它在勾选下当远程资源更新时,本地不会主动更新,而是需要我们手动触发,暂时让它自动更新。

Default Local Group设置

选中你的Addressables Groups 中的默认分组Default Local Group

  • Prevent Updates 取消勾选,这样该Group后面可以针对变化内容进行更新构建。
  • Build&Load Paths 构建和加载地址,选择Remote地址。
  • Include in Build 需要勾选,这样初始整包会包含这个Group
  • Cache Clear Behavior这里选择新版本时进行清理。
  • Bundle Mode 选择Pack Separately为每个资源单独打Bundle,方便检查。
  • Bundle Naming Mode 选择Filename方便检查,且同名会替换旧资源。

测试文件夹分类

这里直接展示最终所需的文件夹和其中的内容,下文会描述他们的作用以及创建步骤。 其中的图片资源需要自己任意找两张尽量相同大小的图片即可,后续会进行替换展示。

测试界面创建

首先创建三个UI 组件里的Button 组件,CloseBtn 是准备用来关闭应用的,LoadBtn 是用来进行加载展示图片的prefabChangeBtn 是用来改变对应prefab 中的图片资源,最后我们创建展示图片用的Image 节点,将其中一张图片拖拽入Image 节点的Source Image 处进行展示,该节点其实是后面需要Addressables 系统中动态加载的prefab 节点,创建好后展示如下。 PS :记得将Image 节点拖入Prefab 文件夹中形成预制件,同时删除Canvas 节点下的Image 节点噢。

导入所需资源

需要将展示图片的Image 导入Addressables 系统中,这里添加入Default 组,可以通过拖拽,或勾选prefab 栏中顶部的Addressable 进行添加,然后将展示的那张图片也导入其中,另外一张图片暂时不导入,等后续将它通过更新的方式上传过去。

代码内容

首先需要在Script 文件夹下创建C #文件,当前命名是StartTest.cs ,将其拖拽到Canvas节点上成为它的代码组件,以下是实际代码内容:

C# 复制代码
using System.Collections;  
using System.Collections.Generic;  
using UnityEngine;  
using UnityEngine.AddressableAssets;  
using UnityEngine.ResourceManagement.AsyncOperations; 
using UnityEngine.UI; 
  
public class StartTest : MonoBehaviour  
{  
    // 关闭按钮
    public Button CloseBtn;
    // 加载按钮
    public Button LoadBtn;
    // 替换按钮
    public Button ChangeBtn;
    // 设置为Addressables中Prefab的地址
    public string PrefabAddress;
    // 设置为Addressables中Sprite的地址
    public string SpriteAddress;
    private AsyncOperationHandle<GameObject> prefabHandle;
    private AsyncOperationHandle<Sprite> spriteHandle;
    private GameObject backGround;
  
    void Start()  
    {  
        // 初始化Addressables系统(本身会在第一次调用api时初始化,也可以自己在合适的位置提前调用)  
        Addressables.InitializeAsync();

        // 注册关闭按钮的点击事件
        CloseBtn.onClick.AddListener(() => {
            Application.Quit();
        });

        // 注册加载按钮的点击事件
        LoadBtn.onClick.AddListener(() => {
            // 加载Prefab
            LoadPrefab(PrefabAddress);
        });

        // 注册替换按钮的点击事件
        ChangeBtn.onClick.AddListener(() => {
            // 加载Sprite
            LoadSprite(SpriteAddress);
        });

    }  
  
    void LoadPrefab(string address)  
    {  
        // 使用Addressables系统异步加载Prefab  
        prefabHandle = Addressables.LoadAssetAsync<GameObject>(address);  
        prefabHandle.Completed += HandleOnPrefabLoaded;  
    }  
  
    void HandleOnPrefabLoaded(AsyncOperationHandle<GameObject> handle)  
    {  
        if (handle.Status == AsyncOperationStatus.Succeeded)  
        {  
            // Prefab加载成功,实例化Prefab  
            backGround = Instantiate(handle.Result, transform);  
        }  
        else  
        {  
            // 处理加载失败的情况  
            Debug.LogError($"Failed to load prefab: {handle.OperationException}");  
        }  
    }

    void LoadSprite(string address)  
    {  
        // 使用Addressables系统异步加载Sprite  
        spriteHandle = Addressables.LoadAssetAsync<Sprite>(address);  
        spriteHandle.Completed += HandleOnSpriteLoaded;  
    }

    void HandleOnSpriteLoaded(AsyncOperationHandle<Sprite> handle)  
    {  
        if (handle.Status == AsyncOperationStatus.Succeeded)  
        {  
            // Sprite加载成功,替换图片
            Debug.Log("Sprite加载成功,替换图片");
            backGround.GetComponent<Image>().sprite = handle.Result;
        }  
        else  
        {  
            // 处理加载失败的情况  
            Debug.LogError($"Failed to load sprite: {handle.OperationException}");  
        }  
    }
  
    void OnDestroy()  
    {  
        // 如果Prefab仍在加载中,取消加载并释放句柄  
        if (prefabHandle.IsValid())  
        {  
            Addressables.Release(prefabHandle);  
        }

        // 如果Sprite仍在加载中,取消加载并释放句柄
        if (spriteHandle.IsValid())  
        {  
            Addressables.Release(spriteHandle);  
        }

        // 如果Prefab实例仍然存在,则销毁它  
        if (backGround != null)  
        {  
            Destroy(backGround);  
        }
    }  
}

构建打包

通过编辑器左上方 File -> Build Settings 打开构建设置,如下图进行设置,最后点击Build 按钮进行创建。(构建结果可以创建一个文件夹放入其中,这里我是TEST 项目根目录下的Out 文件夹) 打包完成后,我们分别可以去对应路径查看构建后的文件:

  • TEST\ServerData\StandaloneWindows64:存放构建的Bundles,目前只有预制件和图片。
  • TEST\Assets\AddressableAssetsData\Windows:生成.bin记录文件。
  • TEST\Out:拿来存放构建整包应用的文件夹。

双击TEST\Out\TEST.exe 文件运行构建后的应用,然后点击屏幕中的Load 按钮,这时候Image 将会被Addressables 系统的apiBundle 中加载并实例化展示出来,就可以看到阿尼亚遇到食物兴奋的表情。如果这个时候我们继续点击Change 按钮,就会弹出报错提示(构建设置需要选择Development Build ),找不到我们填入的第二张图片,因为我们一开始并没有将它导入Addressables的组中,接下来我们将进行远程数据的更新,让已经生成的应用能从远端更新下来对应的图片进行替换展示。

更新构建

将第二张图片也导入进Default 组,加入Addressables 的管理,然后点击右侧的 Build -> Update a Previous Build 进行更新构建,这样远端就会更新到第二张图片资源。

等待更新构建完成后,我们再次去Out 目录下启动TEST.exe 应用,依次点击Load 按钮,展示第一张图,Change按钮展示第二张图,这时第二张图就已经能从远端拉取到了。

相关推荐
Thomas_YXQ14 天前
Unity3D项目为什么要使用FairyGUI
开发语言·unity·游戏引擎·unity3d·游戏开发
nicepainkiller14 天前
Flutter 内嵌 unity3d for android
flutter·unity3d
Thomas_YXQ1 个月前
Unity3D ngui和ugui区别与优缺点详解
服务器·游戏·unity·unity3d·游戏开发
Thomas_YXQ1 个月前
Unity3D Lua如何支持面向对象详解
开发语言·游戏·junit·性能优化·lua·unity3d
Thomas游戏开发1 个月前
Unity3D 逻辑服的Entity, ComponentData与System划分详解
前端框架·unity3d·游戏开发
大眼睛姑娘1 个月前
unity运行状态下移动、旋转、缩放控制模型
unity3d
lin zaixi()2 个月前
手把手教你写Unity3D飞机大战(2)天空盒布置
unity3d
Thomas_YXQ2 个月前
Unity3D中管理Shader效果详解
开发语言·游戏·unity·unity3d·游戏开发
羊羊20352 个月前
线性代数:Matrix2x2和Matrix3x3
线性代数·数学建模·unity3d
天人合一peng2 个月前
Unity hub登录时一直无法进入license
unity3d