unity多渠道sdk打包.

by Aklan

ZeaLotSean Modify

转载请注明.


多渠道sdk自动打包工具

unity多渠道sdk打包._第1张图片

unity多渠道sdk打包._第2张图片

ApkBuilder.cs

using GameResBuild;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;

public class ApkBuilder : EditorBase
{
    public string localAndroidSDKPath = Application.dataPath + "/Plugins/Android";

    public int columnCount = 5;

    /// 
    /// 是否打包带AssetBundle的
    /// 
    private bool m_bAssetBundleBuild = false;

    [MenuItem("Build/ZeaLot's MakeApp/ApkBuilder")]
    private static void DrawWindow()
    {
        ApkBuilder window = (ApkBuilder)EditorWindow.GetWindow(typeof(ApkBuilder));
    }

    private void OnGUI()
    {
        AddTitleLabel("BuildConfigEditor, by Aklan\r\nZeaLot Modify");

        if (!OnShow)
        {
            return;
        }

        EditorGUILayout.Space();
        EditorGUILayout.Space();

        EditorGUILayout.BeginHorizontal();
        LeftNameLabel("单行最大显示数量");
        columnCount = EditorGUILayout.IntField(columnCount, GUILayout.Width(fieldWidth / 2));
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.Space();
        EditorGUILayout.Space();

        m_bAssetBundleBuild = EditorGUILayout.Toggle("是否打AssetBundle包", m_bAssetBundleBuild);

        EditorGUILayout.Space();
        EditorGUILayout.Space();

        LeftNameLabel("所有渠道打包");
        if (GUILayout.Button("打包所有渠道", GUILayout.Width(btnWidth)))
        {
            BuildAllApk();
        }

        EditorGUILayout.Space();
        EditorGUILayout.Space();

        LeftNameLabel("单个渠道打包");
        int index = 0;
        foreach (var iter in BuildConfigDic)
        {
            if (index % columnCount == 0)
                EditorGUILayout.BeginHorizontal();

            if (GUILayout.Button(iter.Value.channelName, GUILayout.Width(btnWidth)))
            {
                Debug.Log("Start build single apk");

                if (EditorUtility.DisplayDialog("确认打包", "是否执行_" + iter.Value.channelName + "_打包?", "Yes", "No"))
                {
                    BuildSingleApk(iter.Value.channelName);
                }

                // ShowBuildPath();
            }

            if (index % columnCount == (columnCount - 1))
            {
                EditorGUILayout.EndHorizontal();
            }

            index++;
        }
    }

    /// 
    /// 打包完成后打开目录
    /// 
    private void ShowBuildPath()
    {
        System.Diagnostics.Process.Start(CommonTools.buildPath);
    }

    private void BuildAllApk()
    {
        if (EditorUtility.DisplayDialog("确认打包", "是否执行所有渠道一键打包?", "Yes", "No"))
        {
            Debug.Log("Start build all apk");
            List buildList = BuildConfigDic.Keys.ToList();

            for (int i = 0; i < buildList.Count; i++)
            {
                BuildSingleApk(buildList[i]);
            }

            // ShowBuildPath();
        }
    }

    private void BuildSingleApk(string channelName)
    {
        BuildConfig _config;

        BuildConfigDic.TryGetValue(channelName, out _config);

        if (_config == null)
        {
            return;
        }

        SaveBuildValue(_config);
        AssetsCopyDirectory(_config.androidSDKPath, localAndroidSDKPath);

        // 调用我们自己的打包
        // BuildToAndroid(config);

        if (m_bAssetBundleBuild)
        {
            BuildAssetBundle.OneKeyMakApp();
        }
        else
        {
            BuildAssetBundle.BuildPlayerUnity();
        }
    }

    private void AssetsCopyDirectory(string fromPath, string toPath)
    {
        Debug.LogWarning("Del_" + toPath + ":" + FileUtil.DeleteFileOrDirectory(toPath));

        AssetDatabase.Refresh();

        if (!Directory.Exists(fromPath))
        {
            return;
        }

        if (!Directory.Exists(toPath))
        {
            Directory.CreateDirectory(toPath);
        }

        string[] files = Directory.GetFiles(fromPath + "/");

        foreach (string file in files)
        {
            string name = file.Substring(file.LastIndexOf("/"));
            FileUtil.CopyFileOrDirectory(file, toPath + "/" + name);
        }

        string[] dirs = Directory.GetDirectories(fromPath + "/");
        foreach (string dir in dirs)
        {
            string name = dir.Substring(dir.LastIndexOf("/"));

            string _path = Path.Combine(name, toPath);

            //UnityEngine.Debug.LogError(toPath);
            //UnityEngine.Debug.LogError(name);
            //UnityEngine.Debug.LogError(_path);

            FileUtil.CopyFileOrDirectory(dir, toPath + "/" + name);
            // FileUtil.CopyFileOrDirectory(dir, _path);
        }

        AssetDatabase.Refresh();
    }

    public void SaveBuildValue(BuildConfig _config)
    {
        PlayerSettings.bundleIdentifier = _config.bundleIdentifier;
        PlayerSettings.bundleVersion = _config.bundleVersion;
        PlayerSettings.Android.bundleVersionCode = _config.bundleVersionCode;
        PlayerSettings.Android.keystoreName = _config.keystorePath;
        PlayerSettings.Android.keystorePass = _config.keystorePassword;
        PlayerSettings.Android.keyaliasName = _config.keyName;
        PlayerSettings.Android.keyaliasPass = _config.keyPassword;
        PlayerSettings.productName = _config.appName;
        PlayerSettings.companyName = _config.companyName;

        if (BuildAssetBundle.IsOSXEditor())
        {
            PlayerSettings.SetIconsForTargetGroup(BuildTargetGroup.Unknown, new Texture2D[] { Resources.Load(_config.iconPath) as Texture2D });
        }
        else
        {
            // 之前的如果sdk里面有会被sdk覆盖
            //PlayerSettings.SetIconsForTargetGroup(BuildTargetGroup.Unknown, new Texture2D[] { Resources.Load(_config.iconPath) as Texture2D });
            // 无效
            //PlayerSettings.SetIconsForTargetGroup(BuildTargetGroup.Android, new Texture2D[] { Resources.Load(_config.iconPath) as Texture2D });

            Texture2D _tex2d = Resources.Load(_config.iconPath) as Texture2D;

            if (_tex2d != null)
            {
                PlayerSettings.SetIconsForTargetGroup(BuildTargetGroup.Android,
                                                      new Texture2D[] { _tex2d, _tex2d, _tex2d,
                                                                        _tex2d, _tex2d, _tex2d });
            }
            else
            {
                UnityEngine.Debug.LogError("Texture2D is Null");
            }
        }

        PlayerSettings.Android.useAPKExpansionFiles = _config.m_bUsePKExpansionFiles;

        UnityEngine.Debug.LogWarning("SaveBuildValue");
    }
}

BuildConfigEditor.cs

using System;
using System.Linq;
using UnityEditor;
using UnityEngine;

/// 
/// sdk编辑框
/// 
public class BuildConfigEditor : EditorBase
{
    private BuildConfig CurrentConfig;
    private bool CreateNew;
    private string ChannelName;
    private int SelectIndex;
    private Texture AppIcon = null;

    // Out Look Parameters

    private Vector2 scrollViewVector2 = Vector2.zero;

    [MenuItem("Build/ZeaLot's MakeApp/ConfigEditor")]
    private static void DrawWindow()
    {
        BuildConfigEditor window = (BuildConfigEditor)EditorWindow.GetWindow(typeof(BuildConfigEditor));
    }

    private BuildConfig AddNewConfig(string channelName)
    {
        BuildConfig config = new BuildConfig(channelName);
        BuildConfigDic.Add(channelName, config);
        return config;
    }

    private void Delete()
    {
        BuildConfigDic.Remove(CurrentConfig.channelName);
        CommonTools.SaveXml(BuildConfigDic);
        SelectIndex -= 1;
    }

    protected override void OnEnabling()
    {
        CreateNew = false;
        SelectIndex = 0;
    }

    private void OnGUI()
    {
        string[] tempList;
        AddTitleLabel("BuildConfigEditor, by Aklan\r\nZeaLot Modify");

        EditorGUILayout.Space();
        EditorGUILayout.Space();

        if (!OnShow) return;

        // 是否要新增配置
        CreateNew = EditorGUILayout.BeginToggleGroup("创建新配置", CreateNew);
        ChannelName = EditorGUILayout.TextField("渠道名", ChannelName, GUILayout.Width(labelWidth + fieldWidth));
        if (!string.IsNullOrEmpty(ChannelName))
        {
            if (GUILayout.Button("Create", GUILayout.Width(btnWidth)))
            {
                if (!BuildConfigDic.ContainsKey(ChannelName))
                {
                    AddNewConfig(ChannelName);
                    // 把index切换到新增的这个配置
                    tempList = BuildConfigDic.Keys.ToArray();
                    for (int i = 0; i < tempList.Length; i++)
                    {
                        if (tempList[i] == ChannelName)
                        {
                            SelectIndex = i;
                            break;
                        }
                    }
                    CreateNew = false;
                }
            }
        }
        EditorGUILayout.EndToggleGroup();

        EditorGUILayout.Space();
        EditorGUILayout.Space();

        if (!CreateNew)
        {
            // 选择一个做显示
            LeftNameLabel("选择要编辑的渠道配置", 400);
            tempList = BuildConfigDic.Keys.ToArray();
            SelectIndex = EditorGUILayout.Popup(SelectIndex, tempList, GUILayout.Width(fieldWidth));
            if (SelectIndex < tempList.Length && SelectIndex >= 0)
            {
                BuildConfigDic.TryGetValue(tempList[SelectIndex], out CurrentConfig);

                EditorGUILayout.Space();
                EditorGUILayout.Space();

                // 图标
                LeftNameLabel("应用图标");
                EditorGUILayout.BeginHorizontal();
                if (GUILayout.Button("Select Icon", GUILayout.Width(btnWidth)))
                {
                    CurrentConfig.iconPath = EditorUtility.OpenFilePanel("Select Icon", "", "png");
                    if (!string.IsNullOrEmpty(CurrentConfig.iconPath))
                    {
                        string[] temp = CurrentConfig.iconPath.Split(new string[] { "Resources/" }, StringSplitOptions.None);
                        CurrentConfig.iconPath = temp[1];
                        CurrentConfig.iconPath = CurrentConfig.iconPath.Split(new string[] { ".png" }, StringSplitOptions.None)[0];
                    }
                }
                AppIcon = Resources.Load(CurrentConfig.iconPath) as Texture;
                if (AppIcon != null)
                    EditorGUI.DrawPreviewTexture(new Rect(170, 150, AppIcon.width / 2, AppIcon.height / 2), AppIcon);
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.Space();
                EditorGUILayout.Space();
                EditorGUILayout.Space();

                LeftNameLabel("打包配置相关");
                CurrentConfig.m_bUsePKExpansionFiles = EditorGUILayout.Toggle("是否打分包(apk + obb)", CurrentConfig.m_bUsePKExpansionFiles);

                EditorGUILayout.Space();
                EditorGUILayout.Space();
                EditorGUILayout.Space();

                LeftNameLabel("名字相关");
                CurrentConfig.fileName = EditorGUILayout.TextField("电脑上显示的文件名", CurrentConfig.fileName, GUILayout.Width(labelWidth + fieldWidth));
                CurrentConfig.appName = EditorGUILayout.TextField("手机上显示的游戏名", CurrentConfig.appName, GUILayout.Width(labelWidth + fieldWidth));
                CurrentConfig.companyName = EditorGUILayout.TextField("公司名", CurrentConfig.companyName, GUILayout.Width(labelWidth + fieldWidth));
                EditorGUILayout.Space();

                LeftNameLabel("AndroidSDKPath");
                LeftNameLabel(CurrentConfig.androidSDKPath, labelWidth + fieldWidth);
                if (GUILayout.Button("Select SDK", GUILayout.Width(btnWidth)))
                {
                    CurrentConfig.androidSDKPath = EditorUtility.OpenFolderPanel("Select Android File", CurrentConfig.androidSDKPath, "Android");
                }
                EditorGUILayout.Space();
                EditorGUILayout.Space();

                // 包信息设置//
                EditorGUILayout.BeginHorizontal();
                LeftNameLabel("Bundle Identifier");
                CurrentConfig.bundleIdentifier = EditorGUILayout.TextField(CurrentConfig.bundleIdentifier, GUILayout.Width(fieldWidth));
                LeftNameLabel("Bundle Version");
                CurrentConfig.bundleVersion = EditorGUILayout.TextField(CurrentConfig.bundleVersion, GUILayout.Width(fieldWidth / 2));
                LeftNameLabel("Version Code");
                CurrentConfig.bundleVersionCode = EditorGUILayout.IntField(CurrentConfig.bundleVersionCode, GUILayout.Width(fieldWidth / 2));
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.Space();

                LeftNameLabel("Keystore");
                EditorGUILayout.BeginHorizontal();
                if (GUILayout.Button("Browse Keystore", GUILayout.Width(btnWidth * 2)))
                {
                    CurrentConfig.keystorePath = EditorUtility.OpenFilePanel("Select Keystore", "", "keystore");
                }
                EditorGUILayout.LabelField(CurrentConfig.keystorePath);
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.Space();

                EditorGUILayout.BeginHorizontal();
                LeftNameLabel("Keystore password", 20);
                CurrentConfig.keystorePassword = EditorGUILayout.TextField(CurrentConfig.keystorePassword, GUILayout.Width(fieldWidth - 20));
                EditorGUILayout.EndHorizontal();

                LeftNameLabel("Key");
                EditorGUILayout.BeginHorizontal();
                LeftNameLabel("Name");
                CurrentConfig.keyName = EditorGUILayout.TextField(CurrentConfig.keyName, GUILayout.Width(fieldWidth));
                LeftNameLabel("Password");
                CurrentConfig.keyPassword = EditorGUILayout.TextField(CurrentConfig.keyPassword, GUILayout.Width(fieldWidth));
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.Space();

                EditorGUILayout.BeginHorizontal();
                if (GUILayout.Button("保存配置", GUILayout.Width(btnWidth * 2)))
                {
                    CommonTools.SaveXml(BuildConfigDic);

                    EditorUtility.DisplayDialog("Save Finish!", "Save Finish!", "ok");
                }

                EditorGUILayout.Space();
                if (GUILayout.Button("删除配置", GUILayout.Width(btnWidth * 2)))
                {
                    Delete();
                }
                EditorGUILayout.EndHorizontal();
            }
        }

        EditorGUILayout.Space();
        EditorGUILayout.Space();

        EditorGUILayout.TextArea("\n\n注意事项:\n" +
                                  "把SDK按渠道归类,比如'C:/Users/Aklan/Desktop/SDK/MI'为小米渠道,且不要放到Assets目录下\n" +
                                  "编辑时:\n" +
                                  "1.新建渠道配置,或选择一个要编辑的配置\n" +
                                  "2.选择本渠道包对应的icon\n" +
                                  "3.设置本渠道包的相关名字\n" +
                                  "4.选择SDK目录,比如'C:/Users/Aklan/Desktop/SDK/MI'\n" +
                                  "5.填写包名,版本等信息\n" +
                                  "6.选择keystore\n" +
                                  "7.点击保存或删除\n" +
                                  "注意:路径不能有中文\n\n");
    }
}

BuildDefine.cs

/// 
/// 打包用配置信息
/// 
public class BuildConfig
{
    /// 
    /// 渠道名
    /// 
    public string channelName = "打包时显示的渠道名";

    /// 
    /// icon路径
    /// 
    public string iconPath = "Textures/GameIcon/";

    /// 
    /// 显示在电脑里的文件名
    /// 
    public string fileName = "文件名称";

    /// 
    /// 显示在手机上的应用名
    /// 
    public string appName = "应用名称";

    /// 
    /// 公司名
    /// 
    public string companyName = "公司名称";

    /// 
    /// 处理好的SDK文件夹路径
    /// 
    public string androidSDKPath = "点击按钮选择对应本渠道的SDK目录";

    /// 
    /// 包名
    /// 
    public string bundleIdentifier = "请填写包名";

    /// 
    /// 包版本名
    /// 
    public string bundleVersion = "请填写版本名";

    /// 
    /// 版本号
    /// 
    public int bundleVersionCode = 1;

    /// 
    /// keystore路径
    /// 
    public string keystorePath = "";

    /// 
    /// keystore密码
    /// 
    public string keystorePassword = "";

    /// 
    /// keystore别名
    /// 
    public string keyName = "";

    /// 
    /// keystore别名密码
    /// 
    public string keyPassword = "";

    /// 
    /// 分包
    /// 
    public bool m_bUsePKExpansionFiles = false;

    /// 
    /// 是否使用sdk
    /// 
    public bool m_useSdk = false;

    public BuildConfig()
    {
    }

    public BuildConfig(string channelName)
    {
        this.channelName = channelName;
    }
}

CommonTools.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using UnityEngine;

public static class CommonTools
{
    public static string projectPath = Application.dataPath.Split(new string[] { "Assets" }, StringSplitOptions.None)[0];
    public static string buildPath = projectPath + "Builds/Android/";
    public static string cfgPath = projectPath + "SDK/Config.xml";

    public static void LoadXml(ref Dictionary dic)
    {
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.Load(cfgPath);
        XmlNodeList nodeList = xmlDoc.SelectSingleNode("Config").ChildNodes;
        foreach (XmlNode node in nodeList)
        {
            if (node.Name != "Child") continue;
            BuildConfig config = new BuildConfig();
            config.channelName = AnalyzeXmlToString(node, "channelName");
            config.iconPath = AnalyzeXmlToString(node, "iconPath");
            config.m_bUsePKExpansionFiles = bool.Parse(AnalyzeXmlToString(node, "useAPKExpansionFiles"));
            config.fileName = AnalyzeXmlToString(node, "fileName");
            config.appName = AnalyzeXmlToString(node, "appName");
            config.companyName = AnalyzeXmlToString(node, "companyName");
            config.androidSDKPath = AnalyzeXmlToString(node, "androidSDKPath");
            config.bundleIdentifier = AnalyzeXmlToString(node, "bundleIdentifier");
            config.bundleVersion = AnalyzeXmlToString(node, "bundleVersion");
            config.bundleVersionCode = AnalyzeXmlToInt(node, "bundleVersionCode");
            config.keystorePath = AnalyzeXmlToString(node, "keystorePath");
            config.keystorePassword = AnalyzeXmlToString(node, "keystorePassword");
            config.keyName = AnalyzeXmlToString(node, "keyName");
            config.keyPassword = AnalyzeXmlToString(node, "keyPassword");
            dic.Add(config.channelName, config);
        }
    }

    public static void SaveXml(Dictionary dic)
    {
        File.Delete(cfgPath);

        XmlDocument xmlDoc = new XmlDocument();
        //创建Xml声明部分,即
        XmlDeclaration dec = xmlDoc.CreateXmlDeclaration("1.0", "utf-8", null);
        xmlDoc.AppendChild(dec);
        XmlNode rootNode = xmlDoc.CreateElement("Config");
        xmlDoc.AppendChild(rootNode);

        foreach (var iter in dic)
        {
            XmlNode child = xmlDoc.CreateElement("Child");

            XmlAttribute attr = xmlDoc.CreateAttribute("channelName");
            attr.Value = iter.Value.channelName;
            child.Attributes.Append(attr);

            attr = xmlDoc.CreateAttribute("iconPath");
            attr.Value = iter.Value.iconPath;
            child.Attributes.Append(attr);

            attr = xmlDoc.CreateAttribute("useAPKExpansionFiles");
            attr.Value = iter.Value.m_bUsePKExpansionFiles.ToString();
            child.Attributes.Append(attr);

            attr = xmlDoc.CreateAttribute("fileName");
            attr.Value = iter.Value.fileName;
            child.Attributes.Append(attr);

            attr = xmlDoc.CreateAttribute("appName");
            attr.Value = iter.Value.appName;
            child.Attributes.Append(attr);

            attr = xmlDoc.CreateAttribute("companyName");
            attr.Value = iter.Value.companyName;
            child.Attributes.Append(attr);

            attr = xmlDoc.CreateAttribute("androidSDKPath");
            attr.Value = iter.Value.androidSDKPath;
            child.Attributes.Append(attr);

            attr = xmlDoc.CreateAttribute("bundleIdentifier");
            attr.Value = iter.Value.bundleIdentifier;
            child.Attributes.Append(attr);

            attr = xmlDoc.CreateAttribute("bundleVersion");
            attr.Value = iter.Value.bundleVersion;
            child.Attributes.Append(attr);

            attr = xmlDoc.CreateAttribute("bundleVersionCode");
            attr.Value = iter.Value.bundleVersionCode.ToString();
            child.Attributes.Append(attr);

            attr = xmlDoc.CreateAttribute("keystorePath");
            attr.Value = iter.Value.keystorePath;
            child.Attributes.Append(attr);

            attr = xmlDoc.CreateAttribute("keystorePassword");
            attr.Value = iter.Value.keystorePassword;
            child.Attributes.Append(attr);

            attr = xmlDoc.CreateAttribute("keyName");
            attr.Value = iter.Value.keyName;
            child.Attributes.Append(attr);

            attr = xmlDoc.CreateAttribute("keyPassword");
            attr.Value = iter.Value.keyPassword;
            child.Attributes.Append(attr);

            rootNode.AppendChild(child);
        }
        xmlDoc.Save(cfgPath);
    }

    private static int AnalyzeXmlToInt(XmlNode node, string key)
    {
        if (node.Attributes[key] != null)
        {
            string tempValue = node.Attributes[key].Value;
            if (tempValue.Length > 0)
                return int.Parse(tempValue);
        }
        return 0;
    }

    private static string AnalyzeXmlToString(XmlNode node, string key)
    {
        if (node.Attributes[key] != null)
            return node.Attributes[key].Value;
        return "";
    }
}

EditorBase.cs

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

public class EditorBase : EditorWindow
{
    protected bool OnShow = false;
    protected Dictionary BuildConfigDic = new Dictionary();

    protected GUIStyle titleStyle = new GUIStyle();
    protected GUIStyleState titleState = new GUIStyleState();
    protected static float totalWidth = 650;
    protected float btnWidth = 100;
    protected float labelWidth = 100;
    protected float fieldWidth = 150;
    protected float border = 4;

    protected virtual void OnEnabling()
    {
    }

    protected void LeftNameLabel(string name, float offsetWidth = 0)
    {
        EditorGUILayout.LabelField(name, GUILayout.Width(labelWidth + offsetWidth));
    }

    protected void AddTitleLabel(string title)
    {
        EditorGUILayout.Space();
        EditorGUILayout.LabelField(new GUIContent(title), titleStyle);
        EditorGUILayout.Space();
    }

    private void OnEnable()
    {
        OnShow = false;
        BuildConfigDic.Clear();
        titleState.textColor = Color.white;
        titleStyle.normal = titleState;
        titleStyle.fontStyle = FontStyle.Bold;
        CommonTools.LoadXml(ref BuildConfigDic);
        OnEnabling();
        OnShow = true;
    }
}

你可能感兴趣的:(unity多渠道sdk打包.)