[Unity热更新]tolua# & LuaFramework(二):打包工具

1.资源的创建

注意一下命名规则,一个面板及其相关的东西都放在同一个文件夹中,如果文件夹命名为xxx,则面板预制要命名为xxxPanel


2.打包

以文件夹为单位进行打包,打包类为Packager.cs。这里要打包的东西分两种,一种为图片等资源,另一种为代码资源(即lua脚本)。对lua脚本的打包已经被框架搞好了,不需要我们考虑,我们要考虑的是对前者的打包,详细的见Packager.cs的HandleExampleBundle方法,这里我做了个小工具:

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

public enum SuffixEnum
{
    Prefab,
    Png,
    Csv,
    Txt,
}

public class AddBuildMapUtility : EditorWindow {

    int count = 0;
    List<string> bundleNameList = new List<string>();
    List<SuffixEnum> suffixList = new List<SuffixEnum>();
    List<string> pathList = new List<string>();

    Vector2 scrollValue = Vector2.zero;

    [MenuItem("LuaFramework/AddBuildMapUtility")]
    static void SetAssetBundleNameExtension()
    {
        EditorWindow.GetWindow<AddBuildMapUtility>();
    }

    void OnGUI()
    {
        EditorGUILayout.BeginHorizontal();
        if (GUILayout.Button("添加一项"))
        {
            AddItem();
        }
        if (GUILayout.Button("清除所有项"))
        {
            Clear();
        }
        if (GUILayout.Button("读取文件(.csv)"))
        {
            Clear();

            string path = EditorUtility.OpenFilePanel("", Application.dataPath, "csv");
            string content = File.ReadAllText(path);
            string[] contents = content.Split(new string[] { "\r\n" }, System.StringSplitOptions.RemoveEmptyEntries);

            for (int i = 0; i < contents.Length; i++)
            {
                string[] a = contents[i].Split(',');
                AddItem(a[0], StringToEnum(a[1]), a[2]);
            }
        }
        if (GUILayout.Button("保存"))
        {
            string path = EditorUtility.SaveFilePanel("", Application.dataPath, "AssetBundleInfo", "csv");
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < count; i++)
            {
                if (string.IsNullOrEmpty(bundleNameList[i])) break;
                sb.Append(bundleNameList[i] + ",");
                sb.Append(EnumToString(suffixList[i]) + ",");
                sb.Append(pathList[i] + "\r\n");
            }
            File.WriteAllText(path, sb.ToString());
            AssetDatabase.Refresh();
        }
        if (GUILayout.Button("自动填写(所有选中的)"))
        {
            int startIndex = count;
            for (int i = 0; i < Selection.objects.Length; i++)
            {
                AddItem();
                AutoFill(startIndex, Selection.objects[i]);
                startIndex++;
            }
        }
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.LabelField("注意:请以文件夹为单位进行选择!!!文件夹名即为包名!!!");

        scrollValue = EditorGUILayout.BeginScrollView(scrollValue);
        for (int i = 0; i < count; i++)
        {
            EditorGUILayout.BeginVertical();
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField(i.ToString() + "AB包名");
            bundleNameList[i] = EditorGUILayout.TextField("", bundleNameList[i]);
            suffixList[i] = (SuffixEnum)EditorGUILayout.EnumPopup("类型", suffixList[i]);
            pathList[i] = EditorGUILayout.TextField("路径", pathList[i]);

            if (GUILayout.Button("自动填写(单个)"))
            {
                AutoFill(i, Selection.objects[0]);
            }
            if (GUILayout.Button("输出路径"))
            {
                Debug.Log(pathList[i]);
            }
            if (GUILayout.Button("删除该项"))
            {
                RemoveItem(i);
            }
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.EndVertical();
        }
        EditorGUILayout.EndScrollView();
    }

    void Clear()
    {
        count = 0;
        bundleNameList = new List<string>();
        suffixList = new List<SuffixEnum>();
        pathList = new List<string>();
    }

    void AddItem(string bundleName = "", SuffixEnum suffix = SuffixEnum.Prefab, string path = "")
    {
        count++;
        bundleNameList.Add(bundleName);
        suffixList.Add(suffix);
        pathList.Add(path);
    }

    void RemoveItem(int index)
    {
        count--;
        bundleNameList.Remove(bundleNameList[index]);
        suffixList.Remove(suffixList[index]);
        pathList.Remove(pathList[index]);
    }

    void AutoFill(int index, Object selectedObject)
    {
        string path = AssetDatabase.GetAssetPath(selectedObject);
        bundleNameList[index] = path.Remove(0, path.LastIndexOf("/") + 1).ToLower() + LuaFramework.AppConst.ExtName;
        
        string[] files = Directory.GetFiles(path);
        string[] temp = files[0].Split('.');
        suffixList[index] = StringToEnum("*." + temp[1]);

        pathList[index] = path;
    }

    public static string EnumToString(SuffixEnum se)
    {
        switch (se)
        {
            case SuffixEnum.Prefab:
                return "*.prefab";
            case SuffixEnum.Png:
                return "*.png";
            case SuffixEnum.Csv:
                return "*.csv";
            case SuffixEnum.Txt:
                return "*.txt";
            default:
                return "null";
        }
    }

    public static SuffixEnum StringToEnum(string s)
    {
        switch (s)
        {
            case "*.prefab":
                return SuffixEnum.Prefab;
            case "*.png":
                return SuffixEnum.Png;
            case "*.csv":
                return SuffixEnum.Csv;
            case "*.txt":
                return SuffixEnum.Txt;
            default:
                return SuffixEnum.Prefab;
        }
    }

} 



[Unity热更新]tolua# & LuaFramework(二):打包工具_第1张图片


然后对HandleExampleBundle这个方法进行修改:

UGUI版本:

    static void HandleExampleBundle()
    {
        string resPath = AppDataPath + "/" + AppConst.AssetDir + "/";
        if (!Directory.Exists(resPath)) Directory.CreateDirectory(resPath);

        //AddBuildMap("prompt" + AppConst.ExtName, "*.prefab", "Assets/LuaFramework/Examples/Builds/Prompt");
        //AddBuildMap("message" + AppConst.ExtName, "*.prefab", "Assets/LuaFramework/Examples/Builds/Message");

        //AddBuildMap("prompt_asset" + AppConst.ExtName, "*.png", "Assets/LuaFramework/Examples/Textures/Prompt");
        //AddBuildMap("shared_asset" + AppConst.ExtName, "*.png", "Assets/LuaFramework/Examples/Textures/Shared");

        string content = File.ReadAllText(Application.dataPath + "/AssetBundleInfo.csv");
        string[] contents = content.Split(new string[] { "\r\n" }, System.StringSplitOptions.RemoveEmptyEntries);
        for (int i = 0; i < contents.Length; i++)
        {
            string[] a = contents[i].Split(',');
            //UnityEngine.Debug.Log(a[0]); UnityEngine.Debug.Log(a[1]); UnityEngine.Debug.Log(a[2]);
            AddBuildMap(a[0], a[1], a[2]);
        }
    }

NGUI版本:

NGUI版本有些不同,它使用的是4.x的打包方式,为了配合5.x的打包,需要修改一下:

[Unity热更新]tolua# & LuaFramework(二):打包工具_第2张图片

    static void HandleExampleBundle(BuildTarget target) {
        Object mainAsset = null;        //主素材名,单个
        Object[] addis = null;     //附加素材名,多个
        string assetfile = string.Empty;  //素材文件名

        BuildAssetBundleOptions options = BuildAssetBundleOptions.UncompressedAssetBundle |
                                          BuildAssetBundleOptions.CollectDependencies |
                                          BuildAssetBundleOptions.DeterministicAssetBundle;
        string dataPath = Util.DataPath;
        if (Directory.Exists(dataPath)) {
            Directory.Delete(dataPath, true);
        }
        string assetPath = AppDataPath + "/StreamingAssets/";
        if (Directory.Exists(dataPath)) {
            Directory.Delete(assetPath, true);
        }
        if (!Directory.Exists(assetPath)) Directory.CreateDirectory(assetPath);

        /////-----------------------------生成共享的关联性素材绑定-------------------------------------
        //BuildPipeline.PushAssetDependencies();

        //assetfile = assetPath + "shared" + AppConst.ExtName;
        //mainAsset = LoadAsset("Shared/Atlas/Dialog.prefab");
        //BuildPipeline.BuildAssetBundle(mainAsset, null, assetfile, options, target);

        /////------------------------------生成PromptPanel素材绑定-----------------------------------
        //BuildPipeline.PushAssetDependencies();
        //mainAsset = LoadAsset("Prompt/Prefabs/PromptPanel.prefab");
        //addis = new Object[1];
        //addis[0] = LoadAsset("Prompt/Prefabs/PromptItem.prefab");
        //assetfile = assetPath + "prompt" + AppConst.ExtName;
        //BuildPipeline.BuildAssetBundle(mainAsset, addis, assetfile, options, target);
        //BuildPipeline.PopAssetDependencies();

        /////------------------------------生成MessagePanel素材绑定-----------------------------------
        //BuildPipeline.PushAssetDependencies();
        //mainAsset = LoadAsset("Message/Prefabs/MessagePanel.prefab");
        //assetfile = assetPath + "message" + AppConst.ExtName;
        //BuildPipeline.BuildAssetBundle(mainAsset, null, assetfile, options, target);
        //BuildPipeline.PopAssetDependencies();

        /////-------------------------------刷新---------------------------------------
        //BuildPipeline.PopAssetDependencies();


        //////////////////////////////////////////////////////////////////////////////
        string content = File.ReadAllText(Application.dataPath + "/AssetBundleInfo.csv");
        string[] contents = content.Split(new string[] { "\r\n" }, System.StringSplitOptions.RemoveEmptyEntries);
        for (int i = 0; i < contents.Length; i++)
        {
            string[] a = contents[i].Split(',');
            //UnityEngine.Debug.Log(a[0]); UnityEngine.Debug.Log(a[1]); UnityEngine.Debug.Log(a[2]);
            AddBuildMap(a[0], a[1], a[2]);
        }

        string resPath = "Assets/" + "StreamingAssets";
        BuildAssetBundleOptions option = BuildAssetBundleOptions.DeterministicAssetBundle |
                                          BuildAssetBundleOptions.UncompressedAssetBundle;
        BuildPipeline.BuildAssetBundles(resPath, maps.ToArray(), option, target);
        maps.Clear();
    }

    static List<AssetBundleBuild> maps = new List<AssetBundleBuild>();
    static void AddBuildMap(string bundleName, string pattern, string path)
    {
        string[] files = Directory.GetFiles(path, pattern);
        if (files.Length == 0) return;

        for (int i = 0; i < files.Length; i++)
        {
            files[i] = files[i].Replace('\\', '/');
        }
        AssetBundleBuild build = new AssetBundleBuild();
        build.assetBundleName = bundleName;
        build.assetNames = files;
        maps.Add(build);
    }


那么,每一次打包,先点击LuaFramework/AddBuildMapUtility,准备好AB包的信息,然后点击LuaFramework/Build xxx Resource来进行打包,在window平台下,检查Assets\StreamingAssets中的资源是否正确。还有最重要的一点,每次对lua文件或者其他资源更改后,都要点击菜单栏LuaFramework/Build xxx Resource来重新打包!



3.编写
a.在Assets\LuaFramework\Lua下的Controller和View下,模仿编写lua
b.在CtrlManager、Game、define这三个lua文件中模仿添加修改东西


4.运行

建立一个空物体,挂上Main脚本,在Canvas(UGUI版本的框架)下建一个空物体,赋予GuiCamera这个tag,将位置和宽高置0,然后拉伸宽高,然后运行,这样就可以了!


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