基于Unity Addressable上传资源到服务器(打Bundle包到服务器)

本文介绍了如何在Unity中使用Addressable进行资源打包,包括更改组名以避免混淆,清除bundle包文件,以及利用编辑器扩展函数实现自动化。在上传阶段,程序将资源文件压缩为Zip并上传至服务器,同时附带模型信息如封面图片、名称、描述、类型和价格。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近公司要求做一个在VR里面的模型商店,自然就绕不开资源打包了,研究了一下Unity最新的Addressable,发现了这玩意是相当好用,只要有配置好bundle包的Json文件路径地址,就可以通过资源的Address轻松加载出资源,开发者不需要管资源之间的各种联系。工程准备的话肯定是要从unity的Package Manager中下载Addressable,下载完之后,对工程做一下简单设置:在Window->AssetMangement->Addressables,添加一个Addressable,在左上角的Profile中,选中Inspect Profile Setting .

这里主要是要打包的时候,把Catalog也要一起生成到指定路径,我这里是生成到本地打包的路径,因为这个路径是固定的,方便后续对打包的文件做压缩操作。

整个程序的工作流程是:①把预制体制作好,拖入组中(一开始组名是Default Group)②更改组名(由于组名相同,打包过程中容易发生混淆,这里为了避免发生不必要的错误,组名使用时间戳保证每次上传的包组名不重复)③运行程序在UI中添加模型必要的信息。④点击上传

UI界面如下:

笔者写了两个编辑器函数去做更改组名和bundle包路径文件的清除:

/****************************************************
    文件:AddressableEditor.cs
	作者:Paul   邮箱: 794451358@qq.com
    日期:2020/7/23 15:23:1
	功能:编辑器扩展函数
*****************************************************/


using UnityEngine;
using System.Collections.Generic;
using System.Collections;
using System;
#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.AddressableAssets;
using UnityEditor.AddressableAssets.Settings;
namespace AddressOperation
{
    public class AddressableEditor : Editor
    {
        [MenuItem("Daschow/1.ChangeGroupName",priority =1)]
        public static void ChangeGroupName()
        {
            AddressableAssetSettingsDefaultObject.Settings.DefaultGroup.Name = GetTimeStamp();
            AddressableAssetSettings.BuildPlayerContent();
            EditorApplication.isPlaying = true;
           
        }

        [MenuItem("Daschow/2.DeleBundleFiles", priority = 2)]
        public static void DeleBundlePathFiles()
        {
           FileUtil.DeleteFileOrDirectory(ProjectConst.BundlePath);
            

        }

        public static string GetTimeStamp()
        {
            //TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            //DateTime.Now.ToString()
            return DateTime.Now.ToString("yyyyMMddhhmmss");
        }

    }

}
#endif

在点击文件上传的时候,程序会利用ICSharpCode.SharpZipLib.Zip工具包把Addressable生成的三个文件(一个记录资源信息的Catalog Json文件,一个bundle包,一个hash文件)压缩成一个Zip压缩包,然后把这个压缩包文件以二进制的格式放入上传表单,上传到服务器。和压缩包一起上传的还有封面图片(这张封面图片是主程序加载模型时UI选择的Icon)、模型的名字(不同于模型的Address,这个是显示给玩家看的模型名字)、资源描述、资源类型还有商品价格。这些必要信息再主程序加载时的必要信息。

附上上传面板的代码:

/****************************************************
    文件:AssetInfoPanel.cs
	作者:Paul   邮箱: 794451358@qq.com
    日期:2020/7/23 12:15:21
	功能:资源信息面板
*****************************************************/


using UnityEngine;
using System.Collections.Generic;
using System.Collections;
using PFarmeWork;
using DG.Tweening;
using UnityEngine.UI;
using WebGLPage;
using UniRx;
#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.AddressableAssets;
using UnityEditor.AddressableAssets.Settings;
#endif
namespace AddressOperation
{
    public class AssetInfoPanel : BasePanel
    {
        public static string AssetName = "";
       
        private Text Text_GroupName;
        private Text Text_AssetName;
        private Text Text_LabelName;
        private RawImage Image_Cover;
        private Button Btn_UpLoad;
        private Camera m_ShotCamera;
        private UpLoadFile m_UpLoader;
        private Slider Sld_CoverProgress;
        private Text Text_CoverProgress;
        private Slider Sld_ZipProgress;
        private Text Text_ZipProgress;
        private InputField Input_Des;
        private InputField Input_ObjName;
        private Dropdown Drop_ObjType;
        private InputField Input_Cost;
        private static string ms_ImgPath = "";

        private static string ms_PhoneNum = "";

        public string PhoneNum { set { value = ms_PhoneNum; } }



        private void Awake()
        {
            Text_GroupName = transform.Find("Text_GroupName").GetComponent<Text>();
            Text_AssetName = transform.Find("Text_AssetName").GetComponent<Text>();
            Text_LabelName = transform.Find("Text_LabelName").GetComponent<Text>();
            Image_Cover = transform.Find("Image_Cover").GetComponent<RawImage>();
            Btn_UpLoad = transform.Find("Btn_UpLoad").GetComponent<Button>();
            m_ShotCamera = GameObject.Find("ShotCamera").GetComponent<Camera>();
            Sld_CoverProgress = transform.Find("Sld_Progress").GetComponent<Slider>();
            Sld_ZipProgress = transform.Find("Sld_ZipProgress ").GetComponent<Slider>();
            Text_CoverProgress = Sld_CoverProgress.transform.Find("Text_Progress").GetComponent<Text>();
            Text_ZipProgress = Sld_ZipProgress.transform.Find("Text_Progress").GetComponent<Text>();
            Input_Des = transform.Find("Input_Des").GetComponent<InputField>();
            Input_ObjName = transform.Find("Input_ObjName").GetComponent<InputField>();
            Drop_ObjType = transform.Find("Drop_ObjType").GetComponent<Dropdown>();
            Input_Cost = transform.Find("Input_Cost").GetComponent<InputField>();


            AddListener<float>(MEventType.CoverUpLoadProgress, OnCoverProChange);
            AddListener<float>(MEventType.BundleUpLoadProgress, OnZipProChange);


        }
        public override void OnEnter()
        {
            m_UpLoader = GetComponentInParent<UpLoadFile>();
            Drop_ObjType.OnValueChangedAsObservable().
                Subscribe(value =>
                {
                    m_UpLoader.Type = value.ToString();
                });
            this.ShowGo();
            GetComponent<CanvasGroup>().DOFade(1, 1f);
#if UNITY_EDITOR
            Text_GroupName.text = AddressableAssetSettingsDefaultObject.Settings.DefaultGroup.Name;
            foreach (var item in AddressableAssetSettingsDefaultObject.Settings.DefaultGroup.entries)
            {
                Text_AssetName.text = item.address.ToString();
                AssetName = item.address.ToString(); 
                foreach (var m_item in item.labels)
                {
                    Text_LabelName.text =  m_item;
                }
                
            }
            Image_Cover.texture = Resources.Load<RenderTexture>("RenderTexture/ShotTexture") as RenderTexture;
            Btn_UpLoad.onClick.AddListener(OnBtnUpLoadDown);
#endif

        }

        public override void OnExit()
        {
            this.HideGo();
            GetComponent<CanvasGroup>().DOFade(0, 1f);
        }

        public override void OnPause()
        {
            base.OnPause();
        }

        public override void OnResume()
        {
            base.OnResume();
        }

        public void OnBtnUpLoadDown()
        {
            ms_ImgPath = ProjectConst.StreamingAssetsPath + Text_AssetName.text + ProjectConst.PNG;
            CameraShot.SaveShot(m_ShotCamera, ms_ImgPath);
            Compress();
            m_UpLoader.Des = Input_Des.text;
            m_UpLoader.ObjName = Input_ObjName.text;
            m_UpLoader.Cost = Input_Cost.text;
            m_UpLoader.UpLoad(ms_ImgPath);

           

        }
        public void OnDropdownChange()
        {
            print(Drop_ObjType.value);
        }

        public void OnCoverProChange(float progress)
        {
            Sld_CoverProgress.value = progress;
            Text_CoverProgress.text = Mathf.Floor(progress*100).ToString() + "%";
        }
        public void OnZipProChange(float progress)
        {
            Sld_ZipProgress.value = progress;
            Text_ZipProgress.text = Mathf.Floor(progress * 100).ToString() + "%";
        }

        private void Compress()
        {
            PFarmeWork. FileUtil.CreateFolder(ProjectConst.ZipDesFolder);
            string[] fileList;
            bool isExits = PFarmeWork.FileUtil.GetDiectoryFilesList(ProjectConst.BundlePath, out fileList);
            if (isExits)
            {
                ZipOperation.ZipFiles(fileList, ProjectConst.ZipDesFileName);
               //m_UpLoader.UpLoadZip(ProjectConst.ZipDesFileName);
            }
        }
        private void OnDestroy()
        {
            RemoveListener<float>(MEventType.CoverUpLoadProgress,OnCoverProChange);
            RemoveListener<float>(MEventType.BundleUpLoadProgress, OnZipProChange);
        }
    }

}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

int_Paul

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值