使用UnityEditor制作可视化打包AssetBundle(二)

Unity版本:Unity 5.6.6f2

基本流程

  • 同步或异步方式读取assetbundle本地文件
  • clone一个gameobject
// LocalFileMgr.cs
using System.IO;
using UnityEngine;

public class LocalFileMgr
{
    #region 单例
    private static LocalFileMgr instance;

    public static LocalFileMgr Instance
    {
        get
        {
            if(instance == null )
            {
                instance = new LocalFileMgr();
            }

            return instance;
        }
    }
    #endregion

#if UNITY_EDITOR

    #if UNITY_STANDALONE
        public readonly string LocalFilePath = Application.dataPath + "/../AssetBundles/Windows/";
    #elif UNITY_IPHONE
        public readonly string LocalFilePath = Application.dataPath + "/../AssetBundles/iOS/";
    #elif UNITY_ANDROID
        public readonly string LocalFilePath = Application.dataPath + "/../AssetBundles/Android/";
    #endif

#elif UNITY_STANDALONE || UNITY_IPHONE || UNITY_ANDROID
    public readonly string LocalFilePath = Application.persistentDataPath + "/"; 
#endif


    /// <summary>
    /// 加载本地资源文件 保存到byte数组
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    public byte[] LoadByteArrayFromLocalFile(string path)
    {
        byte[] buffer = null;
        using (FileStream fs = new FileStream(path, FileMode.Open))
        {
            buffer = new byte[fs.Length];
            fs.Read(buffer, 0, buffer.Length);
        }

        return buffer;
    }
}

同步读取操作

// AssetBundleLoaderSync.cs
using System; 
using UnityEngine;


public class AssetBundleLoaderSync : IDisposable
{
    private AssetBundle bundle;

    public AssetBundleLoaderSync(string assetsPath)
    {
        string fullPath = LocalFileMgr.Instance.LocalFilePath + assetsPath;
        bundle = AssetBundle.LoadFromMemory(LocalFileMgr.Instance.LoadByteArrayFromLocalFile(fullPath));
    }

    public T LoadAsset<T> (string name) where T : UnityEngine.Object
    {
        if (bundle == null) return default(T);
        return bundle.LoadAsset(name) as T;
    }

    public void Dispose()
    {
        if (bundle != null) bundle.Unload(false);
    }
}

异步读取操作

// AssetBundleLoaderAsync.cs
using System.Collections;
using UnityEngine;

public class AssetBundleLoaderAsync: MonoBehaviour
{
    private string m_FullPath;
    private string m_Name;

    AssetBundleCreateRequest abRequest = new AssetBundleCreateRequest();
    AssetBundle bundle = new AssetBundle();

    public System.Action<UnityEngine.Object> OnLoadComplete;

    public void Init(string assetPath, string assetName)
    {
        m_FullPath = LocalFileMgr.Instance.LocalFilePath + assetPath;
        m_Name = assetName;
    }

    void Start()
    {
        StartCoroutine(Load());
    }

    private IEnumerator Load()
    {
        abRequest = AssetBundle.LoadFromMemoryAsync(LocalFileMgr.Instance.LoadByteArrayFromLocalFile(m_FullPath));
        yield return abRequest;
        bundle = abRequest.assetBundle;
        if (OnLoadComplete != null)
        {
            OnLoadComplete(bundle.LoadAsset(m_Name));
            Destroy(this.gameObject);
        }        
    }

    void OnDestroy()
    {
        if (bundle != null) bundle.Unload(false);
        m_FullPath = null;
        m_Name = null;
    }
}

管理类提供两种读取方式的入口

// AssetBundleMgr.cs
using UnityEngine;

public class AssetBundleMgr 
{
    #region 单例
    private static AssetBundleMgr instance;

    public static AssetBundleMgr Instance
    {
        get
        {
            if(instance == null )
            {
                instance = new AssetBundleMgr();
            }

            return instance;
        }
    }
    #endregion

    public GameObject Load(string assetPath, string assetName)
    {
        using (AssetBundleLoaderSync loader = new AssetBundleLoaderSync(assetPath))
        {
            if (loader != null)
            {
                GameObject go = loader.LoadAsset<GameObject>(assetName);
                if (go != null)
                    return go;
            }

            return null;
        } 
    }

    public GameObject LoadClone(string assetPath, string assetName)
    {
        using (AssetBundleLoaderSync loader = new AssetBundleLoaderSync(assetPath))
        {
            if (loader != null)
            {
                GameObject go = loader.LoadAsset<GameObject>(assetName);
                if(go != null)
                    return GameObject.Instantiate(go);
            }

            return null;
        }
    }

    public AssetBundleLoaderAsync LoadAsync(string assetPath, string assetName)
    {
        GameObject go = new GameObject("AssetBundleLoaderAsync");
        AssetBundleLoaderAsync abAsync = go.GetOrCreateGO<AssetBundleLoaderAsync>();
        abAsync.Init(assetPath, assetName);
        return abAsync;
    }
}

测试类中调用:

// Test.cs 
using UnityEngine;

public class Test : MonoBehaviour
{
    void Start()
    {
        AssetBundleMgr.Instance.LoadClone(@"Role\maincity_role_cike.assetbundle", "MainCity_Role_Cike");

        // 异步调用需要在回调函数中实现clone
        AssetBundleMgr.Instance.LoadAsync(@"Role\maincity_role_cike.assetbundle", "MainCity_Role_Cike").OnLoadComplete = (Object go) => {
            Instantiate(go);
        };
    } 
}

期间可能会遇到材质球丢失的问题,这是因为Unity的配置只有默认几个shader,而如果没有把自定义的shader配置上,打包后就会丢失shader,配置方法如下:

Edit -> Project Setting -> Graphics 

红框内是我自己用到的一个shader,加入后重新打包再加载即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值