Unity3d 5.x AssetBundle打包与加载

1.AssetBundle打包

unity 5.x版本AssetBundle打包,只需要设置好AssetBundle的名称后,unity会自动将其打包,无需处理其他,唯独需要做的是设置好个AssetBundle的名称。

注意:AssetBunlde的名称只能设置小写字母,即使你写成大写也会被自动转置成大写字母,而且名称中支持“/”,如:“AssetBundles/cube.unity3d”,.unity3d的后缀是自己设置的,可以不设置

代码:

using UnityEngine;
using UnityEditor;
using System.IO;

public class CreateAssetBundles : Editor {

    [MenuItem("Tools/Build AssetBundles")]
    static void BuildAllAssetBundles()
    {
        BuildPipeline.BuildAssetBundles(Application.dataPath + "/AssetBundles", BuildAssetBundleOptions.ChunkBasedCompression, BuildTarget.Android);
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
        Debug.LogWarning("打包成功");
    }

    [MenuItem("Tools/设置固定名")]
    public static void saveAsStaticName()
    {
        string Path = "Prefabs";
        string abName = "building.ab";
        SetVersionDirAssetName(Path, abName);//第一个参数是路径 第二个参数是Ab名字 默认前缀为 Application.dataPath + "/"+ Path
    }

    [MenuItem("Tools/设定文件名")]
    public static void saveAsPrefabName()
    {
        string Path = "Prefabs";
        SetAssetNameAsPrefabName(Path);//第一个参数是路径
    }

    public static void SetVersionDirAssetName(string fullPath, string abName)
    {
        var relativeLen = fullPath.Length + 8; // Assets 长度
        fullPath = Application.dataPath + "/" + fullPath + "/";

        if (Directory.Exists(fullPath))
        {
            EditorUtility.DisplayProgressBar("设置AssetName名称", "正在设置AssetName名称中...", 0f);
            var dir = new DirectoryInfo(fullPath);
            var files = dir.GetFiles("*", SearchOption.AllDirectories);
            for (var i = 0; i < files.Length; ++i)
            {
                var fileInfo = files[i];
                EditorUtility.DisplayProgressBar("设置AssetName名称", "正在设置AssetName名称中...", 1f * i / files.Length);
                if (!fileInfo.Name.EndsWith(".meta"))
                {
                    var basePath = fileInfo.FullName.Substring(fullPath.Length - relativeLen);//.Replace(‘\\‘, ‘/‘);
                    var importer = AssetImporter.GetAtPath(basePath);
                    if (importer && importer.assetBundleName != abName)
                    {
                        importer.assetBundleName = abName;
                    }
                }
            }
            EditorUtility.ClearProgressBar();
        }
    }

    public static void SetAssetNameAsPrefabName(string fullPath)
    {
        var relativeLen = fullPath.Length + 8; // Assets 长度
        fullPath = Application.dataPath + "/" + fullPath + "/";

        if (Directory.Exists(fullPath))
        {
            EditorUtility.DisplayProgressBar("设置AssetName名称", "正在设置AssetName名称中...", 0f);
            var dir = new DirectoryInfo(fullPath);
            var files = dir.GetFiles("*", SearchOption.AllDirectories);
            for (var i = 0; i < files.Length; ++i)
            {
                var fileInfo = files[i];
                string abName = fileInfo.Name;
                EditorUtility.DisplayProgressBar("设置AssetName名称", "正在设置AssetName名称中...", 1f * i / files.Length);
                if (!fileInfo.Name.EndsWith(".meta"))
                {
                    var basePath = fileInfo.FullName.Substring(fullPath.Length - relativeLen);//.Replace(‘\\‘, ‘/‘);
                    var importer = AssetImporter.GetAtPath(basePath);
                    //abName = AssetDatabase.AssetPathToGUID(basePath);
                    if (importer && importer.assetBundleName != abName)
                    {
                        importer.assetBundleName = abName;
                    }
                }
            }
            EditorUtility.ClearProgressBar();
        }
    }

    /// <summary>
    /// AssetBundleManifestName == 对应AB依赖列表文件
    /// </summary>  

    private static string AssetBundle_BuildDirectory_Path = @Application.streamingAssetsPath + "/../../../" + "AssetBundles";
    private static string AssetBundle_TargetDirectory_Path = @Application.streamingAssetsPath + "/" + "ABFiles";
    [MenuItem("Tools/Asset Bundle/Build Asset Bundles", false, 0)]
    public static void BuildAssetBundleAndroid()
    {
        //Application.streamingAssetsPath对应的StreamingAssets的子目录
        DirectoryInfo AB_Directory = new DirectoryInfo(AssetBundle_BuildDirectory_Path);
        if (!AB_Directory.Exists)
        {
            AB_Directory.Create();
        }
        FileInfo[] filesAB = AB_Directory.GetFiles();
        foreach (var item in filesAB)
        {
            Debug.Log("******删除旧文件:" + item.FullName + "******");
            item.Delete();
        }
#if UNITY_ANDROID
        BuildPipeline.BuildAssetBundles(AB_Directory.FullName, BuildAssetBundleOptions.ChunkBasedCompression, BuildTarget.Android);
#elif UNITY_IPHONE
        BuildPipeline.BuildAssetBundles(AB_Directory.FullName, BuildAssetBundleOptions.ChunkBasedCompression, BuildTarget.iOS);
#else
        BuildPipeline.BuildAssetBundles(AB_Directory.FullName, BuildAssetBundleOptions.ChunkBasedCompression, BuildTarget.StandaloneWindows64);
#endif
        Debug.Log("******AssetBundle打包完成******");

        Debug.Log("将要转移的文件夹是:" + AssetBundle_TargetDirectory_Path);
        FileInfo[] filesAB_temp = AB_Directory.GetFiles();

        DirectoryInfo streaming_Directory = new DirectoryInfo(AssetBundle_TargetDirectory_Path);

        FileInfo[] streaming_files = streaming_Directory.GetFiles();
        foreach (var item in streaming_files)
        {
            item.Delete();
        }
        AssetDatabase.Refresh();
        foreach (var item in filesAB_temp)
        {
            if (item.Extension == "")
            {
                item.CopyTo(AssetBundle_TargetDirectory_Path + "/" + item.Name, true);
            }
        }
        AssetDatabase.Refresh();
        Debug.Log("******文件传输完成******");
    }

    private static string _dirName = "";
    /// <summary>
    /// 批量命名所选文件夹下资源的AssetBundleName.
    /// </summary>
    [MenuItem("Tools/Asset Bundle/Set Asset Bundle Name")]
    static void SetSelectFolderFileBundleName()
    {
        UnityEngine.Object[] selObj = Selection.GetFiltered(typeof(Object), SelectionMode.Unfiltered);
        foreach (Object item in selObj)
        {
            string objPath = AssetDatabase.GetAssetPath(item);
            DirectoryInfo dirInfo = new DirectoryInfo(objPath);
            if (dirInfo == null)
            {
                Debug.LogError("******请检查,是否选中了非文件夹对象******");
                return;
            }
            _dirName = dirInfo.Name;

            string filePath = dirInfo.FullName.Replace(‘\\‘, ‘/‘);
            filePath = filePath.Replace(Application.dataPath, "Assets");
            AssetImporter ai = AssetImporter.GetAtPath(filePath);
            ai.assetBundleName = _dirName;

            SetAssetBundleName(dirInfo);
        }
        AssetDatabase.Refresh();
        Debug.Log("******批量设置AssetBundle名称成功******");
    }
    static void SetAssetBundleName(DirectoryInfo dirInfo)
    {
        FileSystemInfo[] files = dirInfo.GetFileSystemInfos();
        foreach (FileSystemInfo file in files)
        {
            if (file is FileInfo && file.Extension != ".meta" && file.Extension != ".txt")
            {
                string filePath = file.FullName.Replace(‘\\‘, ‘/‘);
                filePath = filePath.Replace(Application.dataPath, "Assets");
                AssetImporter ai = AssetImporter.GetAtPath(filePath);
                ai.assetBundleName = _dirName;
            }
            else if (file is DirectoryInfo)
            {
                string filePath = file.FullName.Replace(‘\\‘, ‘/‘);
                filePath = filePath.Replace(Application.dataPath, "Assets");
                AssetImporter ai = AssetImporter.GetAtPath(filePath);
                ai.assetBundleName = _dirName;
                SetAssetBundleName(file as DirectoryInfo);
            }
        }
    }
    /// <summary>
    /// 批量清空所选文件夹下资源的AssetBundleName.
    /// </summary>
    [MenuItem("Tools/Asset Bundle/Reset Asset Bundle Name")]
    static void ResetSelectFolderFileBundleName()
    {
        UnityEngine.Object[] selObj = Selection.GetFiltered(typeof(UnityEngine.Object), SelectionMode.Unfiltered);
        foreach (UnityEngine.Object item in selObj)
        {
            string objPath = AssetDatabase.GetAssetPath(item);
            DirectoryInfo dirInfo = new DirectoryInfo(objPath);
            if (dirInfo == null)
            {
                Debug.LogError("******请检查,是否选中了非文件夹对象******");
                return;
            }
            _dirName = null;

            string filePath = dirInfo.FullName.Replace(‘\\‘, ‘/‘);
            filePath = filePath.Replace(Application.dataPath, "Assets");
            AssetImporter ai = AssetImporter.GetAtPath(filePath);
            ai.assetBundleName = _dirName;

            SetAssetBundleName(dirInfo);
        }
        AssetDatabase.Refresh();
        Debug.Log("******批量清除AssetBundle名称成功******");
    }
}

上述代码中有一些测试函数,使用时可进行测试

2.AssetBundle加载

下述代码中,cube,sphere等都是在unity项目中自己创建的3d预制体,自行创建即可。创建完成使用1中的方法打包AssetBundle。注意代码中的cube大小写问题,小写的是设置的AssetBundle名称,大写的是Cube预制体的名称,不要混淆。

代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AssetBundleLoad : MonoBehaviour {

    // Use this for initialization
    void Start () {
        this.load1();
        //this.load2();
        //this.load3();
        //this.load4();
    }

    void load1()
    {
        //1.先加载cube后加载sphere
        //这种方式并没有先加载cube的依赖文件,按理说应该加载出来的cube上是sphere是missing的,但是unity5.6.3f1
        //加载并未missing,不知是不是unity版本的优化,不过好习惯还是先加载依赖文件,如load2()。

        //加载assetbundlemanifest文件
        AssetBundle assetBundleManifest = AssetBundle.LoadFromFile(Application.dataPath + "/AssetBundles/AssetBundles");
        if(null != assetBundleManifest)
        {
            AssetBundleManifest manifest = assetBundleManifest.LoadAsset<AssetBundleManifest>("AssetBundleManifest");

            //加载cube
            AssetBundle bundle = AssetBundle.LoadFromFile(Application.dataPath + "/AssetBundles/cube.prefab");
            GameObject obj = bundle.LoadAsset<GameObject>("Cube");
            if(null != obj)
            {
                GameObject cube = Instantiate(obj);
                cube.transform.SetParent(GameObject.Find("UIRoot").transform);
            }

            //加载cube的依赖文件
            string[] depends = manifest.GetAllDependencies("cube.prefab");
            AssetBundle[] dependsAssetbundle = new AssetBundle[depends.Length];
            for(int index = 0; index < depends.Length; ++index)
            {
                dependsAssetbundle[index] = AssetBundle.LoadFromFile(Application.dataPath + "/AssetBundles/" + depends[index]);

                obj = dependsAssetbundle[index].LoadAsset<GameObject>("Sphere");
                if (null != obj)
                {
                    GameObject sphere = Instantiate(obj);
                    sphere.transform.SetParent(GameObject.Find("UIRoot").transform);
                }
            }
        }
    }

    void load2()
    {
        //2.先加载sphere再加载cube

        //加载assetBundleManifest文件
        AssetBundle assetBundleManifest = AssetBundle.LoadFromFile(Application.dataPath + "/AssetBundles/AssetBundles");
        if(null != assetBundleManifest)
        {
            AssetBundleManifest manifest = assetBundleManifest.LoadAsset<AssetBundleManifest>("AssetBundleManifest");

            //加载cube依赖文件
            string[] depends = manifest.GetAllDependencies("cube.prefab");
            AssetBundle[] dependsAssetbundle = new AssetBundle[depends.Length];
            for (int index = 0; index < depends.Length; ++index)
            {
                dependsAssetbundle[index] = AssetBundle.LoadFromFile(Application.dataPath + "/AssetBundles/" + depends[index]);

                GameObject obj1 = dependsAssetbundle[index].LoadAsset<GameObject>("Sphere");
                if (null != obj1)
                {
                    GameObject sphere = Instantiate(obj1);
                    sphere.transform.SetParent(GameObject.Find("UIRoot").transform);
                }
            }

            //加载cube
            AssetBundle bundle = AssetBundle.LoadFromFile(Application.dataPath + "/AssetBundles/cube.prefab");
            GameObject obj = bundle.LoadAsset<GameObject>("Cube");
            if(null != obj)
            {
                GameObject sphere = Instantiate(obj);
                sphere.transform.SetParent(GameObject.Find("UIRoot").transform);
            }
        }
    }

    void load3()
    {
        //3.只加载cube不加载sphere

        //无需加载assetBundleManifest文件,直接加载cube
        AssetBundle bundle = AssetBundle.LoadFromFile(Application.dataPath + "/AssetBundles/cube.prefab");
        GameObject obj = bundle.LoadAsset<GameObject>("Cube");
        if (null != obj)
        {
            GameObject sphere = Instantiate(obj);
            sphere.transform.SetParent(GameObject.Find("UIRoot").transform);
        }
    }

    void load4()
    {
        //4.两个预制打包成同一个AssetBundle

        //无需加载assetBundleManifest文件,直接加载cube
        AssetBundle bundle = AssetBundle.LoadFromFile(Application.dataPath + "/AssetBundles/cube2.prefab");
        GameObject obj = bundle.LoadAsset<GameObject>("Cube_1");
        if (null != obj)
        {
            GameObject cube = Instantiate(obj);
            cube.transform.SetParent(GameObject.Find("UIRoot").transform);
        }

        obj = bundle.LoadAsset<GameObject>("Cube_2");
        if (null != obj)
        {
            GameObject cube = Instantiate(obj);
            cube.transform.SetParent(GameObject.Find("UIRoot").transform);
        }
    }
}

using UnityEngine;

public class Relation : MonoBehaviour {
    //挂在cube预制上的测试脚本
    public GameObject sphere_go;
    public GameObject capsule_go;
    // Use this for initialization
    void Start () {
        ScriptRelation t = new ScriptRelation();
        t.printLog();
    }

    // Update is called once per frame
    void Update () {

    }
}

using UnityEngine;

public class ScriptRelation{

    public void printLog()
    {
        Debug.Log("xxxxxxxxxxxxxxxxxx");
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestAssetBundle : MonoBehaviour {

    public string AssetBundleName = "cube";

    private string dir = "";
    private AssetBundle bundle = null;
    private Object asset = null;
    private GameObject go = null;

    private AssetBundleManifest manifest = null;

    // Use this for initialization
    void Start () {
        dir = Application.dataPath + "/AssetBundles/";
    }

    void OnGUI()
    {
        if (GUILayout.Button("LoadAssetBundle", GUILayout.Width(200), GUILayout.Height(50))) { LoadBundle(); }
        if (GUILayout.Button("LoadAsset", GUILayout.Width(200), GUILayout.Height(50))) { LoadAsset(); }
        if (GUILayout.Button("Instantiate", GUILayout.Width(200), GUILayout.Height(50))) { Instantiate(); }
        if (GUILayout.Button("Destory", GUILayout.Width(200), GUILayout.Height(50))) { Destroy(); }
        if (GUILayout.Button("Unload", GUILayout.Width(200), GUILayout.Height(50))) { UnLoad(); }
        if (GUILayout.Button("UnloadForce", GUILayout.Width(200), GUILayout.Height(50))) { UnLoadForce(); }
        if (GUILayout.Button("UnloadUnusedAssets", GUILayout.Width(200), GUILayout.Height(50))) { UnloadUnusedAssets(); }

        //bundle依赖包加载
        if (GUILayout.Button("LoadAssetBundleManifest", GUILayout.Width(200), GUILayout.Height(50))) { LoadAssetBundleManifest(); }
        if (GUILayout.Button("LoadBundleAndDeps", GUILayout.Width(200), GUILayout.Height(50))) { LoadBundleAndDeps(); }
    }

    void LoadBundle()
    {
        bundle = AssetBundle.LoadFromFile(System.IO.Path.Combine(dir, AssetBundleName));
        if(null == bundle)
        {
            Debug.LogError("LoadBundle Failed");
        }
    }

    void LoadAsset()
    {
        if (null == bundle) return;

        asset = bundle.LoadAsset<Object>("Cube");
        if (null == asset) Debug.LogError("LoadAsset Failed");
    }

    void Instantiate()
    {
        if (null == asset) return;

        go = GameObject.Instantiate<Object>(asset) as GameObject;
        if (null == go) Debug.LogError("Instantiate Failed");
        else
        {
            go.transform.SetParent(GameObject.Find("UIRoot").transform);
        }
    }

    void Destroy()
    {
        if (null == go) return;

        GameObject.Destroy(go);
        go = null;
    }

    /**
     *  AssetBundle.unload(bool unloadAllLoadedObjects) 接口用来卸载AssetBundle文件。
     *  参数为false时,调用该接口后,只会卸载AssetBundle对象自身,并不会影响AssetBundle中加载的Assets。
     *  参数为true时,除了AssetBundle对象自身,所有从当前AssetBundle中加载的Assets也会被同时卸载,不管这个Assets是否还在使用中。
     *  官方推荐参数一般设置为false,只有当很明确知道从AssetsBundle中加载的Assets不会被任何对象引用时,才将参数设置成true。
     **/
    void UnLoad()
    {
        if (null == bundle) return;

        bundle.Unload(false);
        //GameObject.Instantiate<Object>(asset);  //asset可用
        asset = null;
        bundle = null;
    }

    void UnLoadForce()
    {
        if (null == bundle) return;

        bundle.Unload(true);
        //GameObject.Instantiate<Object>(asset);  //报错:asset已被销毁
        asset = null;
        bundle = null;
    }

    void UnloadUnusedAssets()
    {
        Resources.UnloadUnusedAssets();
    }

    void LoadAssetBundleManifest()
    {
        var bundle = AssetBundle.LoadFromFile(System.IO.Path.Combine(dir, "AssetBundles"));
        manifest = bundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");

        //unload
        bundle.Unload(false);
        bundle = null;
    }

    void LoadBundleAndDeps()
    {
        string bundleName = "cube";

        string[] dependence = manifest.GetDirectDependencies(bundleName);
        for(int i=0; i<dependence.Length; ++i)
        {
            AssetBundle.LoadFromFile(System.IO.Path.Combine(dir, dependence[i]));
        }

        var bundle = AssetBundle.LoadFromFile(System.IO.Path.Combine(dir, bundleName));
        var asset = bundle.LoadAsset<GameObject>("Cube");
        bundle.Unload(false);
        bundle = null;
        go = GameObject.Instantiate<GameObject>(asset);
    }
}

上述代码有两个测试脚本,AssetBundleLoad.cs只做了AssetBudle加载的测试。TestAssetBundle.cs做了AssetBundle加载,卸载,使用等测试,比较完整。

3.unity项目中的3个特殊文件夹

a.Resources(只读)

Resources文件夹下的资源会被全部打包到apk或者ipa里面,相当与一个unity默认的AssetBundle,按理说是可以将游戏中所有的资源全部放在Resources进行加载,但是

Resources下的文件数量会影响游戏的启动速度,越多越慢。其次游戏为了降低drawcall,需要对相同材质的图像打包图集,但是如果放在Resources里面是没法打包图集的。

Resources下的资源打包时会进行压缩

b.StreamingAssets(只读)

StreamingAssets文件夹下的资源会被全部打包到apk或者ipa里面

StreamingAssets文件夹下的资源不会影响游戏启动速度

StreamingAssets文件夹下的资源不会被压缩,所以占用内存较大

c.persistentDataPath(可读写)

persistentDataPath文件夹在unity项目中是不存在的,他是程序的沙盒文件夹,只有你游戏安装完成之后,才会存在这个目录,但是它可读写。

综上三种文件夹,我们自己在使用时,Resources里面放的资源只是在本地开发阶段使用,打包的时候会把Resources中的文件都考本出去打成AssetBundle包,然后再将打包好的AssetBundle放到StreamingAssets文件夹下打包apk。

游戏运行时再将资源考本到persistentDataPath文件夹下,因为这个目录可读写,所以能够用来做资源热更新。

如有错误,敬请指正。

参考文章:

http://www.xuanyusong.com/archives/3229

http://www.cnblogs.com/AaronBlogs/p/6837682.html

http://www.cnblogs.com/kanekiken/p/7533510.html

http://www.cnblogs.com/murongxiaopifu/p/4199541.html

http://www.cnblogs.com/jiangshuai52511/p/6437239.html

http://blog.csdn.net/u010377179/article/category/6413676/3

http://blog.csdn.net/suifcd/article/details/51570003

时间: 2024-10-03 19:51:32

Unity3d 5.x AssetBundle打包与加载的相关文章

Unity5 AssetBundle 打包以及加载

using UnityEngine; using System.Collections; using System.Collections.Generic; using UnityEditor; using System.IO; public class BuildAssetBundle : Editor { //需要打包的路径,根据项目具体需求自己定 private static string assetPath = "AllAssets"; //导出包路径 private stat

[Unity]浅谈AssetBundle的依赖关系打包与加载

一.写在前面 通过AssetBundle进行资源管理很方便.AssetBundle的打包与加载策略有很多种,本文来讲一种可以随意通过资源名来加载指定目录下资源的打包方法.意在加深对资源管理的理解. 二.策略介绍 1.打包的粒度划分的策略 ①     所有在指定目录下的文件,即RootList,都被打包成单独结点 ②     对于RootList所依赖的所有资源,即DepList,依赖数大于1的,被打包成单独结点,等于1的,向上合并至被依赖结点. ③     记录打包信息 2.下载策略 ①    

AssetBundle资源打包与加载

AssetBundle资源打包  1.AssetLabels资源标签 文件名:资源打包成AssetBundle后的文件名,类似于压缩包的名字 后缀:自定义 文件名和后缀名都是小写格式(大写会自动转为小写)2. BuildPipeline.BuildAssetBundles(string outputPath, BuildAssetBundleOptions assetBundleOptions, BuildTarget targetPlatform) 打包所有设置了AssetLabel的资源 o

u3d外部资源 打包与加载的问题

被坑了一下午,调bug,u3d外部加载资源一会可以,一会不行,始终找不到问题,最后快下班的时候,重新试了一下,原来是资源打包之前的文件名,和之后的加载资源名必须一样 [MenuItem("Custom Editor/Build AssetBundle From Selection Twice")] static void ExportResourceNoTrack() { // Bring up save panel string path = EditorUtility.SaveFi

Assetbundle创建与加载

[Assetbundle创建与加载] Unity有两种动态加载机制:一种是Resource.Load.一种是AssetBundle.Assetbundle是Unity Pro提供的功能,它可以把多个游戏对象或者资源二进制文件封装到Assetbundle中.供加载.解压使用. [创建Assetbundle] 使用方法 BuildPipeline.BuildAssetBundle (Object, assets , pathName , options , targetPlatform) 参数1:它

Unity3D的坑系列:动态加载dll

Unity3D的坑系列:动态加载dll 我现在参与的项目是做MMO手游,目标平台是Android和iOS,iOS平台不能动态加载dll(什么原因找乔布斯去),可以直接忽略,而在Android平台是可以动态加载dll的,有了这个就可以实现代码更新,不过实际上,在unity里要用上动态加载dll是有很多限制的(不了解的话就是坑). 限制1:在Android手机里动态加载dll不能使用Assembly.LoadFile(string path),只能使用Assembly.Load(byte[] raw

【Unity3d】3d网页游戏场景打包与加载

http://www.cnblogs.com/dosomething/archive/2012/04/07/2436353.html 3d游戏中  一个场景往往比较大  如果游戏的进行需要下载一个10M甚至更大的场景时  加载所用的时间会导致很大部分玩家的流失 我们知道unity3d中的内置地形是使用一张高度图  加载场景时  首先加载地形并显示  再去加载场景中的部件(比如树.房子等)  将会很有必要 在加载场景中的部件时  可以根据玩家当前所在的位置  由近到远的去加载 场景中的每个部件实际

Unity场景打AssetBundle包,加载后天空盒材质丢失问题及解决

环境:win10, Unity2018, vs2015 最近在研究把场景打成AB包进行加载但是发现之前设置的天空盒,这样加载场景后就一片粉了 其实就是材质shader丢失导致天空变粉如上图,如果是直接在Unity里运行这个场景当然是没问题的 那么要解决这个问题,需要几个步骤,还要借助代码(注:这只是我个人的解决办法) Graphics设定Unity菜单:Edit->Prject Settings->Graphics注意在Always Included Shaders选项里把这个Skybox用的

Unity5 AssetBundle系列——资源加载卸载以及AssetBundleManifest的使用

下面代码列出了对于assetbundle资源的常用操作,其中有针对bundle.asset.gameobject三种类型对象的操作,实际使用中尽量保证成对使用. 这一块的操作比较繁琐,但只要使用正确,是可以保证资源完全没有泄露的. using UnityEngine; using System.Collections; public class TestAssetBundle : MonoBehaviour { public string AssetBundleName = "cube1.ass