Unity组件开发--AB包打包工具

这篇具有很好参考价值的文章主要介绍了Unity组件开发--AB包打包工具。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.项目工程路径下创建文件夹:ABundles

unity打包工具,unity组件开发,unity,windows,游戏引擎

unity打包工具,unity组件开发,unity,windows,游戏引擎

2.AB包打包脚本:

using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;

public class AssetBundlePackage {


    static string[] GetBuildScenes() {
        List<string> sceneArray = new List<string>();
        foreach (EditorBuildSettingsScene e in EditorBuildSettings.scenes) {
            if (e == null) continue;
            if (e.enabled) sceneArray.Add(e.path);
        }
        return sceneArray.ToArray();
    }


    [MenuItem("BuildScene/Build")]
    public static void BuildScene() {
        //BundleAssetsBundle_Webgl();

        string folderPath = EditorUtility.OpenFolderPanel("Select Folder", "", "");
        Debug.Log("Selected Folder: " + folderPath);

        BuildPipeline.BuildPlayer(new string[] { "Assets/GameStart.unity" }, folderPath, BuildTarget.WebGL, BuildOptions.AutoRunPlayer);
    }

    [MenuItem("BuildScene/BuildForMobile")]
    public static void BuildSceneForMobile()
    {
        //BundleAssetsBundle_Webgl();

        string folderPath = EditorUtility.OpenFolderPanel("Select Folder", "", "");
        Debug.Log("Selected Folder: " + folderPath);

        BuildPipeline.BuildPlayer(new string[] { "Assets/GameStartMoibile.unity" }, folderPath, BuildTarget.WebGL, BuildOptions.AutoRunPlayer);
    }

    [MenuItem("SceneAsset/BuildCurrent")]
    public static void BuildCurrentScene() {
        string rootPath = Application.dataPath.ToLower().Replace("assets", "") + "ABundles/webgl/scenes";
        string scenePath = EditorSceneManager.GetActiveScene().path;
        string sceneName = System.IO.Path.GetFileNameWithoutExtension(scenePath).ToLower();

        AssetBundleBuild assetBundleBuild = new AssetBundleBuild();
        assetBundleBuild.assetNames = new []{ scenePath };
        assetBundleBuild.assetBundleName = sceneName + ".bundle";
        BuildPipeline.BuildAssetBundles(rootPath, new AssetBundleBuild[] { assetBundleBuild}, BuildAssetBundleOptions.None, BuildTarget.WebGL);
    }

    [MenuItem("SceneAsset/BuildAllScene")]
    public static void BuildAllScene() {
        bool isOk = EditorUtility.DisplayDialog("确认框", "是否将所有场景打成AB包", "确认", "取消");
        if (!isOk) {
            return;
        }

        //AB包路径是ABundles
        string rootPath = Application.dataPath.ToLower().Replace("assets","") + "ABundles/webgl/scenes";
        var allScenesPath = GetBuildScenes();
        foreach (var scenePath in allScenesPath) {
            string sceneName = System.IO.Path.GetFileNameWithoutExtension(scenePath).ToLower();
            AssetBundleBuild assetBundleBuild = new AssetBundleBuild();
            assetBundleBuild.assetNames = new[] { scenePath };
            assetBundleBuild.assetBundleName = sceneName + ".bundle";
            Debug.Log(sceneName + scenePath);
            BuildPipeline.BuildAssetBundles(rootPath, new AssetBundleBuild[] { assetBundleBuild }, BuildAssetBundleOptions.None, BuildTarget.WebGL);
        }
    }


    [MenuItem("AssetBundle/BuildWebGL")]
    public static void BundleAssetsBundle_Webgl() {
        Debug.Log("BundleAssetsBundle WebGL");
        BuildAllAssetBundles();
    }
    private static void BuildAssetsBundle(BuildTarget target) {
        //string packagePath = Application.streamingAssetsPath;
        //if (packagePath.Length <= 0 && !Directory.Exists(packagePath))
        //{
        //    return;
        //}
        //BuildPipeline.BuildAssetBundles(packagePath, BuildAssetBundleOptions.UncompressedAssetBundle, target);
    }
    //Asset/BundleAsset/Prefab/Com/a.bundle  Prefab/Com/a
    public static string RemovePrefix(string inputString) {
        inputString = inputString.Replace("\\", "/");
        string prefix = "Assets/BundleAsset/";
        string result = inputString.Replace(prefix, "");
        return result.Replace(".bundle", "");
    }
    static void BuildAllAssetBundles() {
        string prefabsFolderPath = "Assets/BundleAsset/Prefab";

        if (!Directory.Exists(prefabsFolderPath)) {
            Debug.LogError($"Folder {prefabsFolderPath} does not exist!");
            return;
        }

        //AB包路径是ABundles
        string rootPath = Application.dataPath.ToLower().Replace("assets", "") + "ABundles/webgl";
        if (!Directory.Exists(rootPath)) {
            Debug.LogError($"Folder {rootPath} does not exist!");
            return;
        }

        string[] prefabGUIDs = AssetDatabase.FindAssets("t:Prefab", new[] { prefabsFolderPath });
        foreach (var prefabGUID in prefabGUIDs) {
            string prefabPath = AssetDatabase.GUIDToAssetPath(prefabGUID);
            GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
            if (prefab == null) {
                continue;
            }
            var assetPath = AssetDatabase.GetAssetPath(prefab);
            var dependencies = GetAllDependencies(assetPath).ToArray();

            var withoutEx = Path.GetFileNameWithoutExtension(prefabPath);

            AssetBundleBuild assetBundleBuild = new AssetBundleBuild();
            assetBundleBuild.assetBundleName = RemovePrefix(withoutEx).ToLower() + ".bundle";
            assetBundleBuild.assetNames = dependencies;
            var directName = Path.GetDirectoryName(assetPath);
            var outPackagePath = $"{rootPath}/{RemovePrefix(directName).ToLower()}";

            Debug.Log($"prefabPath {prefabPath}");
            if (!Directory.Exists(outPackagePath)) {
                Directory.CreateDirectory(outPackagePath);
            }

            BuildPipeline.BuildAssetBundles(outPackagePath, new AssetBundleBuild[] { assetBundleBuild }, BuildAssetBundleOptions.None, BuildTarget.WebGL);
        }

        Debug.Log("BuildAssetBundles ok");
    }

    public static List<string> GetAllDependencies(string assetPath) {
        var list = new List<string>();
        var dependencies = AssetDatabase.GetDependencies(assetPath, false);
        foreach (var dependency in dependencies) {
            if (Path.GetExtension(dependency) == ".cs" || Path.GetExtension(dependency) == ".meta" || Path.GetExtension(dependency) == ".DS_Store") {
                continue;
            }
            list.Add(dependency);
        }
        list.Add(assetPath);
        return list;
    }


}

3.需要打包的场景添加到打包配置:

4.unity编辑器生成菜单:

unity打包工具,unity组件开发,unity,windows,游戏引擎

5.场景加载AB包管理器:文章来源地址https://www.toymoban.com/news/detail-861247.html

using Cysharp.Threading.Tasks;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.SceneManagement;
using System.IO;
using UnityEngine.Networking;
using GLTFast;
using LitJson;
using System.Web;

public class SceneLoader : MonoBehaviour {
    
    public int TemplateId;

    public bool useBundle;

    public bool isDeBug;

    public bool isShowCase;

    public bool isMobileTest;

    [Header("天空盒材质球")]
    public UnityEngine.Material skyboxMaterial;

    bool sceneIsLoaded = false;
    [DllImport("__Internal")]
    private static extern string GetUA();

    public virtual void Awake() {

#if !UNITY_EDITOR && UNITY_WEBGL
          string a = GetUA();
          if (a == "1")
            {
                //PC端
                Debug.Log("当前运行环境在PC端");
                PlayerData.Instance.isRunningPC = true;
            }
            if (a == "2")
            {
                //移动端
                Debug.Log("当前运行环境在移动端");
                PlayerData.Instance.isRunningPC = false;
            }
#endif



#if UNITY_EDITOR

        AppConst.UseAssetBundle = useBundle;

#endif

        AppConst.useShowBundlePath = isShowCase;

        DontDestroyOnLoad(gameObject);
        EventManager.Instance.AddListener(EventName.LoadSceneAction, OnSceneLoad);
        EventManager.Instance.AddListener(EventName.OnSceneCfgLoadEnd, RemoveUnuse);



    }

    public virtual void Start() {

        var fps = transform.Find("FPS");
        if (fps) {
            fps.gameObject.SetActive(isDeBug);
        }

        if (isMobileTest) LoadNetCofig();



    }


    void LoadNetCofig() {
        var configPath = Application.dataPath;

#if UNITY_EDITOR
        var filepath = Path.Combine(Application.dataPath.Replace("Assets", ""), "config.txt");
#else
        var filepath = Path.Combine(Application.dataPath, "config.txt");
#endif
        Debug.Log("configPath" + filepath);
        filepath = filepath.Replace("\\", "/");
        StartCoroutine(LoadFileSetNetwork(filepath));
    }

    IEnumerator LoadFileSetNetwork(string filepath) {
        UnityWebRequest www = UnityWebRequest.Get(filepath);


        yield return www.SendWebRequest();


        if (www.result == UnityWebRequest.Result.ConnectionError || www.result == UnityWebRequest.Result.ProtocolError) {
            Debug.LogError(www.error);
        }
        else {
            string json = www.downloadHandler.text;
            var data = LitJson.JsonMapper.ToObject(json);

            if ((string)data["AssetBundleIP"] != string.Empty) {
                Host.AssetBundleIP = (string)data["AssetBundleIP"];
            }
            Host.gameServer = (string)data["local"];
            Host.ApiHost = (string)data["ApiHost"];
            Host.remote = (string)data["remote"];

            Debug.Log("url config:" + json);
            StartCoroutine(tempLoad());

        }
    }

    public IEnumerator tempLoad() {
        Debug.Log("OnBaelogin" + TemplateId);
        var SceneName = TemplateId.ToString();
#if UNITY_EDITOR
        if (AppConst.UseAssetBundle) {
            yield return AssetBundleManager.Instance.LoadSceneSync(SceneName);
        }
        else {
            yield return SceneManager.LoadSceneAsync(SceneName);
        }
#else
        yield return AssetBundleManager.Instance.LoadSceneSync(SceneName);
#endif

        EventManager.Instance.TriggerEvent(EventName.OnSceneLoaded);
        UIManager.Instance.PushPanel(UIPanelType.MAIN_PANEL); //这里有个坑, 如果把界面放在场景加载之前添加,会出现各种错误乱象
        UIManager.Instance.PushPanel(UIPanelType.HUD_PANEL);
        Debug.Log("DownLoadScenConfig");
        if (HttpHelper.Instance != null) {
            HttpHelper.Instance.GetDefaultSpaceImg();
            HttpHelper.Instance.DownLoadScenConfig();
        }
    }


    private void RemoveUnuse(object sender, EventArgs e) {
        RemoveSceneUnUseDefault();

        ResetSkyBox();
    }


    public void ResetSkyBox() {
        JsonData sceneJson = JsonMapper.ToObject(SceneModel.Instance.sceneJsonInitData);
        if (sceneJson["skyBox"] != null) {

            string imgdata = sceneJson["skyBox"]["body"].ToString();
            string decodedString = HttpUtility.UrlDecode(JsonMapper.ToObject(imgdata)["imgDatas"].ToString());
            StartCoroutine(LoadTexturesAndGenerateCubemap(JsonMapper.ToObject<List<skyImgData>>(decodedString)));
        }

    }

    private IEnumerator LoadTexturesAndGenerateCubemap(List<skyImgData> skyImgDataList) {
        Texture2D[] textures = new Texture2D[skyImgDataList.Count];
        Cubemap cubemap;

        for (int i = 0; i < skyImgDataList.Count; i++) {
            using (UnityWebRequest www = UnityWebRequestTexture.GetTexture(skyImgDataList[i].url)) {
                yield return www.SendWebRequest();

                if (www.result == UnityWebRequest.Result.Success) {
                    Texture2D texture = DownloadHandlerTexture.GetContent(www);
                    textures[i] = texture;
                }
                else {
                    Debug.LogError("Failed to load image: " + www.error);
                    yield break;
                }
            }
        }

        Material material = new Material(skyboxMaterial);

        material.SetTexture("_FrontTex", textures[0]);
        material.SetTexture("_BackTex", textures[1]);
        material.SetTexture("_LeftTex", textures[2]);
        material.SetTexture("_RightTex", textures[3]);
        material.SetTexture("_UpTex", textures[4]);
        material.SetTexture("_DownTex", textures[5]);

        RenderSettings.skybox = material;

    }



    /// <summary>
    /// 移除场景默认设置的那些被删除的板
    /// </summary>
    public void RemoveSceneUnUseDefault() {
        var comVOs = SceneModel.Instance.rootCfg.comCfg.comVOs;
        var scene = SceneManager.GetActiveScene();
        GameObject[] roots = scene.GetRootGameObjects();
        foreach (GameObject root in roots) {
            var loaders = root.GetComponentsInChildren<ComLoader>();
            foreach (var loader in loaders) {
                if (comVOs.TryGetValue(loader.instanceName, out _) == false) {
                    StartCoroutine(waitSeconds(loader.gameObject));
                }
            }
        }
    }

    IEnumerator waitSeconds(GameObject go) {
        yield return new WaitForEndOfFrame();
        GameObject.Destroy(go);
    }






    IEnumerator coLoadSceneAsync() {

        if (PlayerData.Instance.isRunningPC == false) {
            yield return new WaitForSeconds(1f);
        }

#if UNITY_EDITOR
        if (SceneModel.Instance.useGlb == false) {
            PlayerData.Instance.TemplateId = TemplateId;
        }
#endif
        var SceneName = "";

        if (SceneModel.Instance.useGlb == true) {
            SceneName = "1000";
        }
        else {
            if (PlayerData.Instance.isRunningPC) {
                SceneName = PlayerData.Instance.TemplateId.ToString();
            }
            else {
                SceneName = PlayerData.Instance.TemplateId.ToString() + "_mobile";
            }
        }

        Debug.Log("SceneName TemplateId:" + SceneName);
#if UNITY_EDITOR
        if (AppConst.UseAssetBundle) {
            yield return AssetBundleManager.Instance.LoadSceneSync(SceneName);
        }
        else {
            yield return SceneManager.LoadSceneAsync(SceneName);
        }

#else
        yield return AssetBundleManager.Instance.LoadSceneSync(SceneName);
#endif

    }

    /// <summary>
    /// 发布态场景加载完成
    /// </summary>
    /// <param name="arg0"></param>
    /// <param name="arg1"></param>
    private void OnPublishModeSceneLoadSuccess(Scene arg0, LoadSceneMode arg1) {
        UIManager.Instance.PushPanel(UIPanelType.EDITOR_MODE_PANEL);
        UIManager.Instance.PushPanel(UIPanelType.HUD_PANEL);
        EventManager.Instance.TriggerEvent(EventName.OnSceneLoaded);
        HttpHelper.Instance.GetDefaultSpaceImg();
        SceneModel.Instance.setDefaultSceneConfig();

        if (PlayerController.Instance.gameObject.GetComponent<RoleInfoUICtr>()) {
            PlayerController.Instance.gameObject.GetComponent<RoleInfoUICtr>().publicModeForName();
            PlayerController.Instance.gameObject.GetComponent<RoleInfoUICtr>().isShowOwnerObj(true);
        }

        if (SceneModel.Instance.useGlb) {
            EventManager.Instance.TriggerEvent(EventName.onGlbSceneLoad, new GlbLoadEvenArg { url = SceneModel.Instance.glbPath });
        }
    }

    public void OnSceneLoad(object sender, EventArgs e) {

        if (sceneIsLoaded == true) {
            return;
        }
        sceneIsLoaded = true;
        var arg = e as SceneLoadActionArgs;
        Debug.Log("OnSceneLoad:" + arg.state);
        if (arg.state == AppConst.PublicMode) //创建态
        {
            SceneManager.sceneLoaded += OnPublishModeSceneLoadSuccess;
        }
        else { //浏览态

            SceneManager.sceneLoaded += OnViewSceneLoadOk;
        }
        StartCoroutine(coLoadSceneAsync());
    }



    /// <summary>
    /// 浏览态场景加载完成
    /// </summary>
    /// <param name="arg0"></param>
    /// <param name="arg1"></param>
    private void OnViewSceneLoadOk(Scene arg0, LoadSceneMode arg1) {
        EventManager.Instance.TriggerEvent(EventName.OnSceneLoaded);
        if (PlayerData.Instance.isRunningPC == true) {
            UIManager.Instance.PushPanel(UIPanelType.HUD_PANEL);
        }
        //ToastPanel.Show("OnViewSceneLoadOk");
        //AlertPanel.Show("OnViewSceneLoadOk", null);
        //Debug.Log("DownLoadScenConfig");
        //if (HttpHelper.Instance != null)
        //{
        //    HttpHelper.Instance.GetDefaultSpaceImg();
        //    //HttpHelper.Instance.DownLoadScenConfig(); //挪到登陆的时候请求场景数据
        //}


        if (SceneModel.Instance.useGlb) {
            EventManager.Instance.TriggerEvent(EventName.onGlbSceneLoad, new GlbLoadEvenArg { url = SceneModel.Instance.glbPath });
        }


        if (PlayerData.Instance.isRunningPC) {
            SceneModel.Instance.ImplementComLoder();
            UIManager.Instance.PushPanel(UIPanelType.MAIN_PANEL);

        }
        else {
            if (SceneModel.Instance.useGlb) {

                EventManager.Instance.AddListener(EventName.onGlbSceneLoadOK, (s, e) => {

                    StartCoroutine(waitSeconds(1, () => {
                        UIManager.Instance.PushPanel(UIPanelType.MAIN_PANEL);
                    }));

                });

                StartCoroutine(waitSeconds(1, () => {

                    if (SceneModel.Instance.useGlb) {
                        EventManager.Instance.TriggerEvent(EventName.onGlbSceneLoad, new GlbLoadEvenArg { url = SceneModel.Instance.glbPath });
                    }
                }));
            }
            else {

                StartCoroutine(waitSeconds(1, () => {
                    UIManager.Instance.PushPanel(UIPanelType.MAIN_PANEL);
                }));

            }


        }
    }

    private IEnumerator waitSeconds(float scecond, Action call) {
        yield return new WaitForSeconds(scecond);
        call();


    }

    public virtual void Onlogin() {



    }

}

到了这里,关于Unity组件开发--AB包打包工具的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [游戏开发]Unity Addressable打包策略

    Addressables的基础看这篇文章 Addressable全教程 最近公司在写新的框架,决定放弃老的bundle打包方式,使用Addressable,因此我要捋顺新的打包方案,并且解决所有疑问。 打包的最终目的是:build出一堆Bundle文件,而哪些因素会影响出包结果,总结一下有3个关键因素和1个非关键因

    2024年02月17日
    浏览(10)
  • [游戏开发][Unity]Assetbundle打包篇(1)打包流程介绍

    打包与资源加载框架目录 先捋一下打AB包的整体思路,首先,Unity4.6版本之后就使用了全新的打包接口 无论是全新打包还是增量打包都是使用这个API,所以一切的一切,都要围绕这个API开始讲起。 该API有四个参数 string outputPath AssetBundleBuild[] builds BuildAssetBundleOptions assetBundle

    2024年02月10日
    浏览(12)
  • [游戏开发][Unity]Assetbundle打包篇(2)打包资源配置篇

    打包与资源加载框架目录 可视化配置的方式有很多种,Json、XML、以及Unity内置的ScriptableObject序列化 配置文件里要有哪些内容呢,很显然,最重要的就是目标文件路径,其次是权重类型,权重类型有:必要打包型、被引用打包型、忽略类型。为何会有忽略类型呢,是因为我们

    2024年02月09日
    浏览(12)
  • [游戏开发][Unity]Assetbundle打包与资源加载框架

    我会分三个篇章写整个框架分别是: AB打包篇 AB下载篇 AB加载篇 整个框架内容比较多,属于企业级方案,涉及到增量打包、打包策略、AB包下载、边玩边下、资源管理系统,资源加载系统等功能。 Unity小白看本系列文章可能比较吃力。如果我哪里写的不好,影响理解了,欢迎

    2024年02月13日
    浏览(13)
  • [游戏开发][Unity] 打包Xcode工程模拟器+真机调试

    Xcode版本:Xcode14 苹果开发者账号、相关设备cer证书、开发者证书、发布证书 账号分三类,个人,公司,企业,价格99/99/299美金 新注册账号的基本设置按网上的教程来就行 我们公司是企业账号,我的苹果开发者账号是公司一个User,这个和个人开发者不同。 账号还是非常重要

    2024年02月15日
    浏览(17)
  • 【Unity 框架】QFramework v1.0 使用指南 工具篇:13. 其他事件工具 | Unity 游戏框架 | Unity 游戏开发 | Unity 独立游戏

    QFramework 除了支持了 TypeEventSystem、EasyEvent 还支持了 EnumEventSystem、StringEventSystem。 EnumEventSystem 前身是 老版本 QFramework 的 QEventSystem StringEventSystem 的前身是,老版本的 MsgDispatcher TypeEventSystem: 事件体定义简洁 比较适合用于设计框架 支持 struct 获得较好内存性能 使用反射,CPU

    2023年04月17日
    浏览(24)
  • [游戏开发][Unity]Assetbundle打包篇(5)使用Manifest二次构建资源索引

    打包与资源加载框架目录 正文开始前,先把打包代码放过来,请注意,前面的代码已省略,自己去对比前面的文章。本篇文章从第一次执行打包代码开始。 第一次调用BuildPipeline.BuildAssetBundles打包API后(详见代码第七行),会返回AssetBundleManifest的引用, 【疑问】: BuildPipe

    2024年02月03日
    浏览(8)
  • 【Unity 框架】QFramework v1.0 使用指南 工具篇:05. ResKit 资源管理&开发解决方案 | Unity 游戏框架 | Unity 游戏开发 | Unity 独立游戏

    Res Kit,是资源管理快速开发解决方案 特性如下: 可以使用一个 API 从 dataPath、Resources、StreammingAssetPath、PersistentDataPath、网络等地方加载资源。 基于引用计数,简化资源加载和卸载。 拥抱游戏开发流程中的不同阶段 开发阶段不用打 AB 直接从 dataPath 加载。 测试阶段支持只需打

    2024年02月01日
    浏览(18)
  • 【Unity游戏开发基础】如何做可以调整音量的UI滚动条组件

    游戏的设置列表中,调整游戏声音大小的选项是必备的,如何实现拖动滚动条后音量相应改变大小呢?这里介绍一下相关的脚本和步骤 首先,新建一个调整音量的脚本,名叫SetVolume,把预置的Update方法和Start方法删除。 然后,这个脚本需要挂载在滚动元素的Slider组件下。这个

    2024年02月03日
    浏览(16)
  • 【Unity工具,简单学习】PUN 2,多人在线游戏开发,初步使用

    链接 PUN 可以让你 简单地开发多人游戏 ,在 全球范围 推出 让开发者 不用管托管、链接和延迟 支持移动端、台式、一些主机 全球范围内低延迟 始终连接,无需穿透 免费20 CCU(Concurrent User, 并发用户) 支持 Unity 2019 - 2022 安装包,输入邮箱来注册,或输入Appid来登录。 输入邮箱

    2024年02月07日
    浏览(12)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包