ToLua 入门09_Bundle

一段时间没写了,今天把最重要的一节补上;前面说的内容,开发过程都够用了,但是,如果直接用.lua文件去实现热更,未免太不安全了,所有的代码都裸露在大家眼中了;所有我们需要一个东西去对.lua进行加密打包,框架就给我们提供了一个现成的Bundle工具。

具体使用
1.我们依旧打开工程的.\tolua-master\Assets\ToLua\Examples\18_Bundle文件夹,打开TesetAssetBundle场景;直接运行,我们会发现有报错,原因是因为我们都没有打包lua文件,Bundle都没有。
2.打包lua文件,依次点击导航条上lua -> Build bundle files not jit 按钮;进度条走完后,我们会发现StreamingAssets文件夹下出现了Win文件夹,下面有一堆的lua,lua.unity3d文件等;这时候我们再运行,发现不报错,并且有打印了。
ToLua 入门09_Bundle_第1张图片
3.只是有打印了,这自动打包怎么用嘛,大家肯定在想,此刻大家肯定是懵B的;大家可以看下Assets下有一个Lua文件夹,我们Bundle的话,框架会帮我们吧Lua下的Lua文件都自动打包;我们可以试一下,双击打开Lua文件夹下的Main.lua文件。
ToLua 入门09_Bundle_第2张图片
我们此刻改一下打印的信息,将print(“logic start”)改为print(“Test logic start !!!”);删除StreamingAssets下的Win文件夹,继续点击导航条上lua -> Build bundle files not jit 按钮,进度条重新跑了一遍,Win文件夹和下面的打包文件重新又生成了,我们再运行跑一便,发现我们修改的lua内容被打包出去并且运行了。
ToLua 入门09_Bundle_第3张图片
我们发现修改的lua脚本被重新打包出去了。

代码解析
我们接下来打开TestABLoader类,对此类进行分析下。

public class TestABLoader : MonoBehaviour 
{
    int bundleCount = int.MaxValue;
    string tips = null;

    IEnumerator CoLoadBundle(string name, string path)
    {
        using (WWW www = new WWW(path))
        {
            if (www == null)
            {
                Debugger.LogError(name + " bundle not exists");
                yield break;
            }

            yield return www;

            if (www.error != null)
            {
                Debugger.LogError(string.Format("Read {0} failed: {1}", path, www.error));
                yield break;
            }

            --bundleCount;
            LuaFileUtils.Instance.AddSearchBundle(name, www.assetBundle);
            www.Dispose();
        }                     
    }

    IEnumerator LoadFinished()
    {
        while (bundleCount > 0)
        {
            yield return null;
        }

        OnBundleLoad();
    }

    public IEnumerator LoadBundles()
    {
        string streamingPath = Application.streamingAssetsPath.Replace('\\', '/');

#if UNITY_5 || UNITY_2017 || UNITY_2018
#if UNITY_ANDROID && !UNITY_EDITOR
        string main = streamingPath + "/" + LuaConst.osDir + "/" + LuaConst.osDir;
#else
        string main = "file:///" + streamingPath + "/" + LuaConst.osDir + "/" + LuaConst.osDir;
#endif
        WWW www = new WWW(main);
        yield return www;

        AssetBundleManifest manifest = (AssetBundleManifest)www.assetBundle.LoadAsset("AssetBundleManifest");
        List list = new List(manifest.GetAllAssetBundles());        
#else
        //此处应该配表获取
        List list = new List() { "lua.unity3d", "lua_cjson.unity3d", "lua_system.unity3d", "lua_unityengine.unity3d", "lua_protobuf.unity3d", "lua_misc.unity3d", "lua_socket.unity3d", "lua_system_reflection.unity3d" };
#endif
        bundleCount = list.Count;

        for (int i = 0; i < list.Count; i++)
        {
            string str = list[i];

#if UNITY_ANDROID && !UNITY_EDITOR
            string path = streamingPath + "/" + LuaConst.osDir + "/" + str;
#else
            string path = "file:///" + streamingPath + "/" + LuaConst.osDir + "/" + str;
#endif
            string name = Path.GetFileNameWithoutExtension(str);
            StartCoroutine(CoLoadBundle(name, path));            
        }

        yield return StartCoroutine(LoadFinished());
    }

    void Awake()
    {
#if UNITY_5 || UNITY_2017 || UNITY_2018
        Application.logMessageReceived += ShowTips;
#else
        Application.RegisterLogCallback(ShowTips);
#endif
        LuaFileUtils file = new LuaFileUtils();
        file.beZip = true;
#if UNITY_ANDROID && UNITY_EDITOR
        if (IntPtr.Size == 8)
        {
            throw new Exception("can't run this in unity5.x process for 64 bits, switch to pc platform, or run it in android mobile");
        }
#endif
        StartCoroutine(LoadBundles());
    }

    void ShowTips(string msg, string stackTrace, LogType type)
    {
        tips += msg;
        tips += "\r\n";
    }

    void OnGUI()
    {
        GUI.Label(new Rect(Screen.width / 2 - 200, Screen.height / 2 - 150, 400, 300), tips);
    }

    void OnApplicationQuit()
    {
#if UNITY_5 || UNITY_2017 || UNITY_2018
        Application.logMessageReceived -= ShowTips;
#else
        Application.RegisterLogCallback(null);
#endif
    }

    void OnBundleLoad()
    {                
        LuaState state = new LuaState();
        state.Start();
        state.DoString("print('hello tolua#:'..tostring(Vector3.zero))");
        state.DoFile("Main.lua");
        LuaFunction func = state.GetFunction("Main");
        func.Call();
        func.Dispose();
        state.Dispose();
        state = null;
	}	
}

LoadBundles方法为加载Bundle的方法,机制和AB包加载一样的,首先加载Win文件夹下的Win信息索引文件,通过索引文件得到所有相关的Lua打包文件,通过CoLoadBundle方法将得到的所有文件进行初始化;LoadFinished方法等待所有的打包文件初始化完毕,完毕后执行OnBundleLoad方法;OnBundleLoad方法中 ,使用 state.DoFile(“Main.lua”);方法去加载打包后的Main.lua文件,最后使用 LuaFunction func = state.GetFunction(“Main”);func.Call();对Main.lua方法进行实例和调用。
其实很简单,框架所有lua AB打包和解析代码都抛了出来,要是不适应大家完全可以修改为合适自己项目。有了Bundle和之前的知识,已经足够使用开发进行热更开发。

你可能感兴趣的:(unity#tolua)