• IOS使用Unity容器动态加载3D模型


    项目背景

    我们的APP是一个数字藏品平台,里面的很多藏品需要展示3D模型,3D模型里面可能会包含场景,动画,交互。而对应3D场景来说,考虑到要同时支持iOS端,安卓端,Unity是个天然的优秀方案。

    对于Unity容器来说,需要满足如下的功能:

    1.在APP启动时,需要满足动态下载最新的模型文件。

    2.在点击藏品查看模型时,需要根据不同的参数展示不同的模型,并且在页面消失后,自动卸载对应的模型。

    如果要实现上面说的功能则是需要使用Unity的打包功能,将资源打包成AssetBundle资源包,然后把ab包进行上传到后台服务器,然后在APP启动时从服务器动态下载,然后解压到指定的目录中。

    当用户点击藏品进入到Unity容器展示3D模型时,则可以根据传递的模型名称和ab包名,从本地的解压目录中加载对应的3D模型。

    AssetBundle打包流程

    创建AB打包脚本

    AB包打包是在Editer阶段里。

    首先要创建一个Editer目录并把脚本放置到这个目录下面,注意它们的层级关系:Assert/Editor/CS脚本,这个层级关系是固定的,不然会报错。

    0

    脚本实现如下:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    using UnityEditor;

    using System.IO;

    ///

    ///

    ///

    public class AssetBundleEditor

    {

        //1.编译阶段插件声明

        [MenuItem("Assets/Build AssetBundles")]

        static void BuildAssetBundles() {

            string dir = "AssetBundles";

            if (!Directory.Exists(dir)) {

                //2.在工程根目录下创建dir目录

                Directory.CreateDirectory(dir);

            }

            //3.构建AssetBundle资源,AB资源包是一个压缩文件,可以把它看成是一个压缩的文件夹,里面

            //可能包含多个文件,预制件,材质,贴图,声音。

            BuildPipeline.BuildAssetBundles(dir, BuildAssetBundleOptions.None, BuildTarget.iOS);

        }

    }

    设置需要打包的资源

    可以在Project选中一个资源(预制件,材质,贴图,声音等),然后在Inspector下面的AssetBundle设置打包成的名称和后缀。如果名称带层级的如:scene/cube,那么打出来的AB包会自己添加一个scene目录,然后在目录下存在了cube资源包。

    AB包可以存在依赖关系,比如GameObjectA和GameObjectB共同使用了Material3, 然后它们对应的AssetBundle名称和后缀分别为cube.ab, capsule.ab, share.ab。

    虽然GameObjectA中包含了Material3资源,但是 AssetBundle在打包时如果发现Material3已经被打包成了share.ab, 那么就会只打GameObjectA,并在里面设置依赖关系就可以了。

    0

    使用插件工具进行打包

    1.从gitHub上下载源码,然后将代码库中的Editor目录下的文件复制一份,放到工程Target的Assets/Editor目录下。打开的方式是通过点击Window->AssetBundle Browser进行打开

    插件工具地址:GitHub - Unity-Technologies/AssetBundles-Browser: Editor tool for viewing and debugging asset bundle contents before and after builds

    0

    2.打包时,可以选择将打出的ab包内置到项目中,勾选Copy StreamingAssets ,让打出的内容放置在StreamingAssets目录下,这样可以将ab资源内置到Unity项目中。

    3.通过上面的操作会完成资源打包,然后将打包的产物压缩上传到后台。

    0

    AssetsBundle资源包的使用

    APP启动时,下载AssetBundle压缩包, 然后解压放置在沙盒Documents/AssetsBundle目录下,当点击APP中的按钮进入到Unity容器页面时,通过包名加载对应的ab包进行Unity页面展示。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    ///

     ///读取原生沙盒Documents/AssetsBundle目录下的文件,Documents/AssetsBundle下的文件通过Native原生下载的资源

     ///

     /// Documents/AssetsBundle下的ab文件

     /// 读取到的字符串

     public static AssetBundle GetNativeAssetFromDocumentsOnProDownLoad(string abName)

     {

         string localPath = "";

         if (Application.platform == RuntimePlatform.Android)

         {

             localPath = "jar:file://" + Application.persistentDataPath + "/AssetsBundle/" + abName;

         }

         else

         {

             localPath = "file://" + Application.persistentDataPath + "/AssetsBundle/" + abName;

         }

         UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(localPath);

         var operation = request.SendWebRequest();

         while (!operation.isDone)

         { }

         if (request.result == UnityWebRequest.Result.ConnectionError)

         {

             Debug.Log(request.error);

             return null;

         }

         else

         {

             AssetBundle assetBundle = DownloadHandlerAssetBundle.GetContent(request);

             return assetBundle;

         }

         //UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(localPath);

         //yield return request.Send();

         //AssetBundle assetBundle = DownloadHandlerAssetBundle.GetContent(request);

         //return assetBundle;

     }

    注意:当离开Unity容器时需要卸载里面加载的ab包

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    public

  • 相关阅读:
    计算机毕业设计Java百姓点评网的设计与实现(源码+系统+mysql数据库+lw文档)
    C# 中的“智能枚举”:如何在枚举中增加行为
    高考志愿冲稳保策略
    我把MySQL运行在Docker上,差点完了……
    【云原生K8S】Kubernetes资源管理
    STM32G030F6P6TR 芯片TSSOP20 MCU单片机微控制器芯片
    python趣味编程-5分钟实现一个简单弹跳球游戏(含源码、步骤讲解)
    FPGA的汽车尾灯控制Verilog
    【Vue-Element-Admin】select模糊查询
    Spring原理学习(八)AOP底层实现
  • 原文地址:https://blog.csdn.net/xdpcxq/article/details/136520246