AssetBundle动态加载Scene场景

这篇具有很好参考价值的文章主要介绍了AssetBundle动态加载Scene场景。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

加载场景有两种方法,一种是常规的build settings添加scene,一种是通过AssetBundle加载Scene。

using UnityEngine;
using UnityEngine.SceneManagement;

public class SceneTest : MonoBehaviour
{
    void Start()
    {
        SceneManager.LoadSceneAsync("xxx1", LoadSceneMode.Additive);
        SceneManager.LoadSceneAsync("xxx2", LoadSceneMode.Additive);
        SceneManager.LoadSceneAsync("xxx3", LoadSceneMode.Additive);
    }
}

 上面是标准的异步加载场景,如果不在build settings中添加场景,直接加载scene,就会报下面的错。

AssetBundle动态加载Scene场景

因此对于需要热更新的项目,如果场景.unity资源变更了,无法在build settings中重新设置,只能用Assetbundle加载场景。 

下面是打ab包的工具(BuildAssetBundleTool放到Scripts/Editor文件夹下)和标准化路径工具。

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

/// <summary>
/// 构建工具类:
/// 创建了三种构建方法windows android ios。
/// Build方法:从所有路径查找文件,排除meta后,把每个文件名作为被打包资源名和bundle名(当然一个bundle可以打包多个文件)
/// </summary>
public class BuildAssetBundleTool : Editor
{
    //如何使用Build呢,直接添加工具栏
    [MenuItem("Tools/Build Windows Bundle")]
    static void BundleWindowsBuild()
    {
        Build(BuildTarget.StandaloneWindows);
    }

    //如何使用Build呢,直接添加工具栏
    [MenuItem("Tools/Build Android Bundle")]
    static void BundleAndroidBuild()
    {
        Build(BuildTarget.Android);
    }

    //如何使用Build呢,直接添加工具栏
    [MenuItem("Tools/Build IOS Bundle")]
    static void BundleIOSBuild()
    {
        Build(BuildTarget.iOS);
    }

    //为了能够构建多平台,需要把目标平台作为参数传入。
    static void Build(BuildTarget target)
    {
        //主要目的是收集这个build信息,需要打哪些文件,需要给bundle包用一个什么样的名字,BuildAssetBundles函数用到这个Build数组
        List<AssetBundleBuild> assetBundleBuilds = new List<AssetBundleBuild>();

        //第一步搜索出我们这个所有文件的文件名Directory.GetDirectories和Directory.GetFiles对应两种打包策略一个获取文件夹一个获取文件,GetFiles比较简单
        //searchPattern通配符,*是默认 https://www.cnblogs.com/ost/archive/2006/08/20/481625.html
        string[] files = Directory.GetFiles(PathUtil.BuildResourcesPath, "*", SearchOption.AllDirectories);
        //所有文件都找出来了,需要排除调meta文件
        for (int i = 0; i < files.Length; i++)
        {
            if (files[i].EndsWith(".meta"))
            { 
                continue; 
            }
            //创建一个需要build的Bundle
            AssetBundleBuild assetBundle = new AssetBundleBuild();

            //处理出来的路径斜杠可能不同。需要规范一下
            string fileName = PathUtil.GetStandardPath(files[i]);

            string assetName = PathUtil.GetUnityPath(fileName);//获取unity相对路径
			//一个assetBundle可以打包多个文件,这里只放一个文件
            assetBundle.assetNames = new string[] { assetName };//assetBundle是一个相对路径文件名

			//创建包名
            string bundleName = fileName.Replace(PathUtil.BuildResourcesPath, "").ToLower();
            assetBundle.assetBundleName = bundleName + ".ab";//Bundle需要后缀是.ab,,,,,,,,至此,Bundle的信息收集完了,需要放进list

            assetBundleBuilds.Add(assetBundle);
        }

        //为什么不用另一个重载BuildAssetBundles(string outputPath, BuildAssetBundleOptions assetBundleOptions, BuildTarget targetPlatform),是因为需要自己去资源设置bundle名打标签,很麻烦
        //第二个参数把list转为array数组
        //第三个参数是压缩格式,选择默认
        //第四个参数是目标平台,先选择win
        if(Directory.Exists(PathUtil.BundleOutPath))
        {
            //判断是否有路径,如果有这个文件夹,就删掉文件,,递归recursive删掉所有文件和子文件。
            Directory.Delete(PathUtil.BundleOutPath, true);
        }
        Directory.CreateDirectory(PathUtil.BundleOutPath);//删除路径后,创建路径

        BuildPipeline.BuildAssetBundles(PathUtil.BundleOutPath, assetBundleBuilds.ToArray(), BuildAssetBundleOptions.None, target);
    }
}
/// <summary>
/// 路径工具类:
/// 1定义了所有用到的路径
/// 2返回标准路径或返回unity下的几个文件夹的相对路径
/// </summary>
//因为所有路径都要用到,所以写入一个只读变量中,用来后期访问
public class PathUtil
{
    //为什么要把Application定义出来,因为每一次访问都需要GC一次,定义出来就访问一次;
    public static readonly string AssetPath = Application.dataPath;

    //只读的,需要打Bundle的目录
    public static readonly string BuildResourcesPath = AssetPath + "/BuildResources/";

    //Bundle输出目录
    public static readonly string BundleOutPath = Application.streamingAssetsPath;

    /// <summary>
    /// 获取Unity的相对路径
    /// </summary>
    /// <param name="path">绝对路径</param>
    /// <returns></returns>
    public static string GetUnityPath(string path)
    {
        if(string.IsNullOrEmpty(path))
        {
            return string.Empty;
        }
        //从Assets位置拿到相对目录
        return path.Substring(path.IndexOf("Assets"));
    }

    /// <summary>
    /// 获取标准路径
    /// </summary>
    /// <param name="path">路径</param>
    /// <returns></returns>
    public static string GetStandardPath(string path)
    {
        if (string.IsNullOrEmpty(path))
        {
            return string.Empty;
        }
        //先处理空格,在处理反斜杠
        return path.Trim().Replace("\\", "/");
    }
}

这两个工具放到文件夹后,在unity工具栏的位置出现Editor新工具,选择第一个构建Bundle,就可以把创建好的场景打包到StreamingAssets路径下,,,在SceneTest中通过这个路径,加载AssetBundle包,就可以动态加载场景了。

AssetBundle动态加载Scene场景

 重新编写SceneTest场景加载的脚本,挂到起始场景的任意物体上,就可以动态加载场景了。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class sceneTest : MonoBehaviour
{
    // Start is called before the first frame update
    IEnumerator Start()
    {
        yield return LoadSceneAB("xxx1");
        yield return LoadSceneAB("xxx2");
        yield return LoadSceneAB("xxx3");
    }

    IEnumerator LoadSceneAB(string sceneName) 
    {
        string assetBundleName = "scenes/" + sceneName +".unity.ab";
        string path = Application.dataPath + "/StreamingAssets/" + assetBundleName;

        AssetBundleCreateRequest myLoadedAssetBundle = AssetBundle.LoadFromFileAsync(path);

        yield return myLoadedAssetBundle;
        
        if (myLoadedAssetBundle != null)
        {
            SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive);
        }
    }
}

AssetBundle动态加载Scene场景

 运行前后

AssetBundle动态加载Scene场景

 如果该场景中依赖于其他物体、材质等,也是通过打包才能获取的,那么需要将其他物体也通过AssetBundle获取,获取方法需要编写一个依赖文件,说明此资源依赖于哪些资源,并通过递归的方法,加载这些依赖资源的ab包,下次再写这个地方的实现。文章来源地址https://www.toymoban.com/news/detail-506847.html

到了这里,关于AssetBundle动态加载Scene场景的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • [Vue]从数据库中动态加载阿里巴巴矢量图标的两种方式

    记录一次在Vue中动态使用阿里巴巴矢量图标库 这是本人第一次使用阿里巴巴的矢量图标库,简单的导入和使用的话网上的教程很多,这里不多赘述,本人的需求是从数据库中加载出来并且显示到页面上,接下来简述一下如何实现。 以下代码均是本人实际推敲、测试可用后写

    2024年01月20日
    浏览(53)
  • 【Unity】AssetBundle加载与卸载

    需要注意的是同一个ab包一次只能加载一个,不可以同时加载, 报错: The AssetBundle \\\'xxxxx\\\' can\\\'t be loaded because another AssetBundle with the same files is already loaded. 如果AB包已经加载过则先进行卸载: 1、卸载全部的目前没有使用的资源: Resources.UnloadUnusedAssets() 2、卸载 AssetBundle 释放其

    2024年04月25日
    浏览(31)
  • UnityEditor加载AssetBundle模型变为粉色

    Unity游戏开发过程中,在UnityEditor下,我们通常直接使用游戏资产(lua代码,prefab,图片,材质等)。而游戏发布后则通常资产导出为AssetBundle以给游戏使用。 Unity会为不同的平台(android,ios,windows)生成不同的AssetBundle,如果我们在UnityEditor下面直接使用为android或者ios平台生成的

    2024年02月13日
    浏览(44)
  • Android 场景Scene的使用

    Scene 翻译过来是场景,开发者提供起始布局和结束布局,就可以实现布局之间的过渡动画。 具体可参考 使用过渡为布局变化添加动画效果 大白话,在 Activity 的各个页面之间切换,会带有过渡动画。 打个比方,使用起来类似 Fragment ,单 Activity 多 Fragment 的情景下,为 Fragme

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

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

    2024年02月13日
    浏览(55)
  • Unity-AssetBundle Browser 打包和加载

    进入unity手册中,搜素 Unity Asset Bundle Browser 工具,选择你使用的版本号,根据显示出的操作进行资源导入即可。 注:有的版本可能没有资源链接,可以百度一下有很多。 1、制作预制体(省略)  2、选择一个预制体,在Inspector窗口下方,设置预制体的ab包名(包名只能为小写字

    2024年04月13日
    浏览(38)
  • unity scene场景调整好后让game窗口的视角与scene相同

    调整scene中场景视角 选中相机 然后 如果要实现相反的功能  即scene的视角与game的一样则 选中相机

    2024年02月04日
    浏览(32)
  • 【Unity】AssetBundle资源异步加载以及AB包卸载

    以下代码是基于上一篇文章《AssetBundle资源同步加载》的代码新增了异步加载和AB包卸载功能,有兴趣的同学可以去看看我的上一篇文章。 由于异步加载需要配合协程进行功能开发,所以我对之前封装的AB包资源加载管理器进行修改,改为继承MonoBehaviour的单例模式。 主要修改

    2023年04月08日
    浏览(38)
  • Unity脚本之场景(Scene)跳转/转换

    Unity的场景跳转需要用到其自带的场景管理类SceneManage。 想要实现场景跳转首先需要在File--Build Settings里将你需要用到的场景添加进去。 打开Build Settings 1.当前已添加的场景与其序号,左边是场景名,右边是序号。打勾即为会使用该场景。 2.将当前正在打开的场景(Scene)加入到

    2024年04月13日
    浏览(38)
  • Unity中使用AssetBundle打包与加载的注意事项

    一、使用AssetBundle进行打包与加载 个人觉得可以参考以下两篇博客,这个网上相关教程很多,还不明白的可以去百度,或者给我留言。 Unity 打包与加载AssetBundle(加载对应的依赖) Unity中的AssetBundle 二、使用AssetBundle进行加载的时候注意事项: 注意事项一:AssetBundle名字和设置

    2024年02月11日
    浏览(41)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包