Unity 3D 资源的加载与释放

版本:unity 5.4.1  语言:C#

 

海水先在这里坑一会,看了里面的算法深深感到自己数学能力的不足,经过同学的推荐,我准备先看会《数值分析》闭关修炼一下。

 

至于我在看的实战核心技术的第十章MVC设计框架,提供了一堆无用的代码,然后让你去看他的课程,我就自己研究一下如何从Asset中加载到场景中,又如何在场景中释放资源。

 

总结一下网上一共有三种方法(这次最终解决了AssetBundle的加载问题,AssetBundle原来是要打包后才能加载……):静态加载、Resources.Load、AssetBundle.LoadAsset。

 

各有不同的用处吧,本地的话前两个更加容易管理使用,AssetBundle可以用在网络环境下。

 

接下来看代码:

(参考:http://www.taidous.com/portal.php?mod=view&aid=445&page=1)

public class ResManager : MonoBehaviour {

    public GameObject tps;

	void Start ()
    {
        //StartCoroutine(LoadResByResources("TPS"));
        //StartCoroutine(LoadResByStatic());
        StartCoroutine(LoadResByBundle("file://" + Application.dataPath + @"/Resources/rs.assetbundle", "assets/standard assets/characters/thirdpersoncharacter/prefabs/thirdpersoncontroller.prefab"));
    }

    // Resources的方法加载资源,只能在Resources文件夹下读取,不想创建Resources文件夹的可以考虑静态加载
    IEnumerator LoadResByResources(string path)
    {
        Resources.UnloadUnusedAssets();

        // 读取,此时仅读取了资源的少量信息,并不占多少内存
        GameObject go = Resources.Load<GameObject>(path);

        yield return new WaitForSeconds(5f);

        // 创建,如果Instantiate过多会产生卡顿,所以在加载大量资源的时候,考虑对象池
        // 先在读取进度的时候把对象创建出来,并SetActive(false),使用的时候SetActive(true)
        GameObject goInit = Instantiate(go);
        goInit.transform.parent = transform;
        goInit.transform.localPosition = Vector3.zero;
        goInit.transform.localRotation = Quaternion.identity;

        yield return new WaitForSeconds(5f);

        // 销毁对象,但各种资源还占据内存
        Destroy(goInit);

        yield return new WaitForSeconds(5f);

        // 卸载所有没有引用的资源,相当于清空了内存
        // 但最好不要主动使用,转换场景的时候会清空资源
        Resources.UnloadUnusedAssets();
    }

    // 静态的方法加载资源,效果与Resources加载类似
    IEnumerator LoadResByStatic()
    {
        Resources.UnloadUnusedAssets();

        yield return new WaitForSeconds(5f);

        GameObject goInit = Instantiate(tps);
        goInit.transform.parent = transform;
        goInit.transform.localPosition = Vector3.zero;
        goInit.transform.localRotation = Quaternion.identity;

        yield return new WaitForSeconds(5f);
        Destroy(goInit);

        yield return new WaitForSeconds(5f);
        Resources.UnloadUnusedAssets();
    }

    // 使用AssetBundle加载资源,在LoadAsset的时候就会加载大量的资源
    // 所以实例化时加载的资源量反而小,可以考虑利用这种方法做加载而不卡顿
    IEnumerator LoadResByBundle(string path, string name)
    {
        Resources.UnloadUnusedAssets();

        // 建立WWW读取,这边是本地
        WWW bundle = new WWW(path);
        yield return bundle;

        yield return new WaitForSeconds(5f);

        // 从读取到的资源中获取对应prefab
        //Object obj = bundle.assetBundle.Load(name);   //方法已经被废弃
        Object obj = bundle.assetBundle.LoadAsset(name);

        yield return new WaitForSeconds(5f);

        // 实例化
        GameObject goInit = Instantiate(obj) as GameObject;
        goInit.transform.parent = transform;
        goInit.transform.localPosition = Vector3.zero;
        goInit.transform.localRotation = Quaternion.identity;

        yield return new WaitForSeconds(5f);

        // 删除
        Destroy(goInit);

        yield return new WaitForSeconds(5f);

        // Unload释放内存镜像,参数是是否强制删除内存资源
        // true强制删除,即使内存有引用也删除
        //bundle.assetBundle.Unload(true);

        // 删除没有引用的资源,比如说这边,如果调用的是这个方法的的话
        // 虽然资源已经被删除了,但内存中还保留的该prefab,直到调用Resources.UnloadUnusedAssets()
        bundle.assetBundle.Unload(false);

        Resources.UnloadUnusedAssets();
    }

    // 打包方法是jiange啊啊啊撰写的(http://blog.csdn.net/janeky/article/details/17652021)
    // 这个方法是打包当前项目的资源,从而形成assetbundle文件,供LoadResByBundle加载
    [MenuItem("Assets/Build AssetBundle From Selection")]
    static void ExportResourceRGB2()
    {
        // 打开保存面板,获得用户选择的路径  
        string path = EditorUtility.SaveFilePanel("Save Resource", "", "New Resource", "assetbundle");

        if (path.Length != 0)
        {
            // 选择的要保存的对象
            Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
            //打包  
            BuildPipeline.BuildAssetBundle(Selection.activeObject, selection, path, BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets, BuildTarget.StandaloneWindows);
        }
    }
}

静态读取和Resources.Load最好先把要用到的实例出来,嗯,在进度读取的时候做,然后SetActive(false)将其隐藏,这样卡顿现象应该不会出现吧。

 

好了,这本书我看了,再写个热更新吧,其他章节也没什么好看的了。


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值