加载资源:Assets,Resources,AssetsBundle(在线更新)

1、Assets(在编辑器环境加载)
2、Resources(游戏运行时加载)
3、AssetsBundle(在线更新)

Assets(在编辑器环境加载)

UnityEditor.AssetDatabase.LoadAssetAtPath

 Editor下的加载方式,加载路径是项目下的路径,除了Resources文件夹都不会随着打包打到游戏本体内。
注意路径是带Assets开头,并且需要后缀

Texture2D t = AssetDatabase.LoadAssetAtPath("Assets/UI/cube.png", typeof(Texture2D)) as Texture2D;

AssetDataBase不支持异步,所以editor下的效果和打包效果不一样,而且这样的加载还需要后缀,或者用ab名去索引,否则导致会多些一些代码,不过问题不大,习惯就好。
如果DestroyImmediately(true)后除非重启unity,再也加载不出来

Resources

  • Resources类只能读取名为“Resources”的文件夹里的资源,注意是复数形式。
  • Resources文件夹需要用户自己新建,建议创建并放在Asset文件夹的根目录下。
  • Unity打包发布时,Resources文件夹里的资源在会被打入包中。
  • Resources类加载资源时,使用”Resources”文件夹开始的相对路径,且不包含资源的扩展名。如要加载Asset/Resources/Images/1.jpg资源,加载路径应该写”Images/1”。
using UnityEngine;
using System.Collections;

public class TestResources : MonoBehaviour {

    void Start () {
        /*
        加载资源
        */
        // 预制体返回GameObject类型,路径不包含拓展名
        GameObject go = Resources.Load<GameObject>("Prefabs/Cube");
        // 资源在加载后要被实例化才能看到(等于克隆一个出来)
        GameObject go2 = Instantiate(go);

        // 加载其他非GameObject类型的资源
        Texture2D image = Resources.Load<Texture2D>("Images/1");
        // 测试是否加载成功
        Debug.Log(image.name);

        /*
        卸载资源
        */
        // 卸载非GameObject类型的资源,会将已加载资源及其克隆体剔除
        Resources.UnloadAsset(image);
        // 卸载GameObject类型的资源的克隆体
        Destroy(go2);

#if UNITY_EDITOR
        // 在编辑器模式下无法卸载go物体,否则会报错让改用DestroyImmediate(obj, true),但这样做会连文件夹里的原始Asset一并删除!
#else
        DestroyImmediate(go); // 所有该物体的克隆体也都一并被删除,即本例中的go2物体
#endif
    }
}

总结一下:

  • Resources类的资源加载方式只有一种,但卸载方式却有三种,加载容易卸载难。选择有误会报错,甚至会连文件夹里的原始Asset一并删除!
  • Resources.UnloadAsset(obj):卸载 GameObject类型的资源,会将内存中已加载资源及其克隆体卸载。
  • Destroy(obj):仅用于卸载GameObject类型的资源的克隆体
  • DestroyImmediately(obj):卸载GameObject类型的资源,会将内存中已加载资源及其克隆体卸载,但该方法只能用在非编辑模式下,否则会报错提示改为DestroyImmediately(obj, true),然而编辑模式下使用该函数会连文件夹里的原始Asset一并删除。

官方推荐的卸载资源方法是:

public static AsyncOperation UnloadUnusedAssets()//Resources.UnloadUnusedAssets()

从返回值可以看出这是个异步操作,即Unity需要花费一定时间去检索哪些资源没有被使用才会去卸载。使用方便,但不快捷,还要注意哪些资源是否一直被全局变量引用,导致一直无法释放。

AssetsBundle

1、制作AssetBundle

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

public class BuildAssetsBundle{

    [MenuItem("Publish/Build Bundle")]  // 在编辑器上创建打包菜单,BuildBundle为菜单的响应函数
    public static void BuildBundle()
    {
        // 1、生成AssetBundleBuild数组
        List<AssetBundleBuild> builds = new List<AssetBundleBuild>();
        AssetBundleBuild b = new AssetBundleBuild();
        b.assetBundleName = "1.unity3d";    // 打包之后的包体名
        b.assetNames = new string[] { "Assets/Resources/Prefabs/BackpackPanel.prefab" };   // 打包的资源路径,可将多个资源打包进一个包体
        builds.Add(b);

        // 2、打包
        // BuildAssetBundles(输出路径,需要打包的AssetBundleBuild数组,打包方式,平台)
        // 打包方式CollectDependencies:对于一个prefab,将其依赖的资源都打包进去。如prefab有个动画控制器组件,它引用的动画控制器也会打包进去
        // 平台:如果是StandaloneWindows64,则打包出来的资源只能在Windows64位平台上加载
        BuildPipeline.BuildAssetBundles("Assets/Bundle", builds.ToArray(), BuildAssetBundleOptions.CollectDependencies, BuildTarget.StandaloneWindows64);

    }
}

2、从AssetBundle加载资源

using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;

public class LoadAssetBundle : MonoBehaviour {

	// Use this for initialization
	void Start () {
        StartCoroutine(Load());
	}

    IEnumerator Load()
    {
        // 1、使用www加载AssetBundle
        //WWW www = new WWW("http://.../1.unity3d");   // 从网上加载
        //WWW www = new WWW("file://" + Application.streamingAssetsPath + "1.unity3d");   // 从手机上加载,需要在Assets下创建Streaming Assets文件夹,Streaming Assets与Resources两个文件夹都会打包到包体中
        WWW www = new WWW(@"file:///F:\UnityProject\Backpack\Assets\Bundle\1.unity3d"); // Windows上从本地加载
        yield return www;

        // 2、从AssetBundle中加载asset
        AssetBundle bundle = www.assetBundle;
            // 异步加载,分帧,慢点,但不会卡住主线程。参数一为资源路径,参数二为资源类型。参数一的资源路径和资源打包前的路径是一样的
        AssetBundleRequest request = bundle.LoadAssetAsync("Assets/Resources/Prefabs/BackpackPanel.prefab", typeof(GameObject));
        yield return request;
        GameObject go = request.asset as GameObject;
            // 同步加载,不分帧,较快,但资源大就会卡住主线程。
        //GameObject go = bundle.LoadAsset<GameObject>("Assets/Resources/Prefabs/BackpackPanel.prefab");
        Instantiate(go);

        www.Dispose();  // 释放www

        //bundle.Unload(true);  // 完全卸载bundle

        //bundle.Unload(false);   // 部分卸载bundle,正在被使用的不卸载
        //Resources.UnloadUnusedAssets(); // 当不再被使用后,用这个函数来卸载

    }
}

 参考链接:

https://blog.csdn.net/u014528558/article/details/105796076/​​​​​​​

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值