美文网首页
第二章 AutoBuild.BuildPackage

第二章 AutoBuild.BuildPackage

作者: 最怕认真 | 来源:发表于2019-02-12 15:30 被阅读55次

    上一章提到了unity能够自动打包,主要是因为提供了命令行的方式来调用内部代码,而这内部代码就是AutoBuild类的BuildPackage方法。
    想想手动打包时代,我们需要到 File->Build Setting -> 选择场景 -> 选择平台 -> 设置平台参数 -> 最后build。其实这一串操作,Unity都提供了api来设置。

    代码解读

    using UnityEngine;
    using UnityEditor;
    using System;
    using System.IO;
    using UnityEditor.Callbacks;
    using UnityEditor.iOS.Xcode;
    
    public class AutoBuild : Editor
    {
        /// <summary>
        /// 这三个平台值需要和jenkins中的三个值一样
        /// </summary>
        private const string Android = "Android";
        private const string Ios = "Ios";
        private const string Windows = "Windows";
    
        /// <summary>
        /// 这些常量是用来解析外部参数的
        /// </summary>
        private const string Connector = "-";//连接符
        private const string ParameterBundleVersionKey = "bundleVersion";//出包的版本号
        private const string ParameterPlatformKey = "platform";//平台
        private const string ParameterPathKey = "path";//出包路径
    
        private static string path;
        private static string platform;
    
        public static void BuildPackage()
        {
            //注册输出监听,用来处理错误信息
            Application.logMessageReceived += Handler;
           
            platform = GetParameterFromCmd(ParameterPlatformKey);
            path = GetParameterFromCmd(ParameterPathKey);
            PlayerSettings.bundleVersion = GetParameterFromCmd(ParameterBundleVersionKey);
            //取消默认的开场动画
            PlayerSettings.SplashScreen.show = false;
    
    
            switch (platform)
            {
                case Android:
                    BuildApk(path);
                    break;
                case Ios:
                    ExportXCodeProject(path);
                    break;
                case Windows:
                    BuildExe(path);
                    break;
                default:
                    Debug.LogError("平台" + platform + "不存在");
                    throw new Exception("平台错误");
            }
    
        }
    
    
    
        static string GetParameterFromCmd(string key)
        {
            var args = Environment.GetCommandLineArgs();
            foreach (var item in args)
            {
                if (item.Contains(key + Connector))
                    return item.Replace(key + Connector, "");
            }
            Debug.LogError("参数解析出错 kye = " + key + " 不存在");
            throw new Exception("参数解析出错");
        }
    
    
        static void BuildExe(string path)
        {
            BuildPlayerOptions op = new BuildPlayerOptions()
            {
                locationPathName = path/*"F:/test1/sunhouse.exe"*/,
                scenes = EditorBuildSettingsScene.GetActiveSceneList(EditorBuildSettings.scenes),
                target = BuildTarget.StandaloneWindows
            };
            Build(op);
        }
    
    
        static void BuildApk(string path)
        {
    
            PlayerSettings.Android.keystoreName = ".keystore的路径";
            PlayerSettings.Android.keystorePass = "keystore的密码";
            PlayerSettings.Android.keyaliasName = "应用别名";
            PlayerSettings.Android.keyaliasPass = "别名的密码";
            BuildPlayerOptions op = new BuildPlayerOptions()
            {
                locationPathName = path,
                scenes =  EditorBuildSettingsScene.GetActiveSceneList(EditorBuildSettings.scenes),
                target =  BuildTarget.Android
            };
            Build(op);
        }
    
        static void ExportXCodeProject(string path)
        {
            PlayerSettings.iOS.appleDeveloperTeamID = "teamid,在苹果开发者账号中可以找到";
            PlayerSettings.iOS.appleEnableAutomaticSigning = true;//是否自动签名
            PlayerSettings.iOS.targetOSVersionString = "8.0";
            BuildPlayerOptions op = new BuildPlayerOptions()
            {
                locationPathName = path,
                scenes =  EditorBuildSettingsScene.GetActiveSceneList(EditorBuildSettings.scenes),
                target =  BuildTarget.iOS
            };
            Build(op);
        }
    
        static void Build(BuildPlayerOptions op)
        {
            
            string ret = BuildPipeline.BuildPlayer(op);
            if (!string.IsNullOrEmpty(ret))
            {
                //出错了,抛出一个异常让外部知道
                throw new Exception(ret);
            }
        }
    
        private static void Handler(string condition, string stackTrace, LogType type)
        {
            if (type == LogType.Error)
            {
                //将错误写入一个文件中,文件路径为出包路径的根目录
                var fileName = Path.Combine(Path.GetDirectoryName(path), "unityError.txt");
                if (!File.Exists(fileName))
                    File.Create(fileName).Dispose();
                File.AppendAllText(fileName, condition+"\n");
                File.AppendAllText(fileName, stackTrace + "\n\n");
            }
        }
    
    
    
        /// <summary>
        /// 导出包后自动会回调该函数
        /// </summary>
        /// <param name="bulidTarget"></param>
        /// <param name="path"></param>
        [PostProcessBuild]
        public static void OnPostprocessBuild(BuildTarget bulidTarget, string path)
        {
            if (bulidTarget != BuildTarget.iOS) return;
            
            var projectPath = PBXProject.GetPBXProjectPath(path);
            var project = new PBXProject();
            var fileText = File.ReadAllText(projectPath);
            project.ReadFromString((fileText));
            var targetGuid = project.TargetGuidByName(PBXProject.GetUnityTargetName());
            //为xcode工程添加需要的系统framwork,注意这个api只能添加系统framework
            project.AddFrameworkToProject(targetGuid,"AdSupport.framework",true);
            project.AddFrameworkToProject(targetGuid,"CoreBluetooth.framework",true);
            project.WriteToFile(projectPath);
        }
    
    }
    
    

    函数 GetParameterFromCmd的作用,是从命令行中得到参数,这里我们可以定义自己想要的参数,比如平台,比如版本号。
    函数 OnPostprocessBuild是在导出工程或者包体后会调用的一个函数,这里可以对xcode工程进行修改,比如添加framework。其他的操作也可以翻看pbxproject的api。
    PlayerSettings这个类是设置一些常用的公用参数的,比如是否启用开启动画,出包的版本号等等。
    PlayerSettings.iosPlayerSettings.Android对了ios和android平台下特有的参数设置。
    函数 Handler在开头进行了注册,任何的unity输出都会回调它,在这里我们检测打包途中是否有错误发生,如果有则抛出异常,一旦异常抛出,那么外部的程序就会知道,网上的很多其他文章没有考虑到打包失败的情况,一路都是万事如意的代码。

    作用总结

    这个类主要是针对android平台进行apk的导出,以及ios平台xcode的导出并且对xcode工程进行特定的修改。后边如果要对windows平台进行打包,也可以扩展这个类。

    注意事项

    如果在windows上写这些代码,可能会出现xcode的命名空间不存在的情况,只需要在File->Build Setting -> Ios 下下载环境即可
    这个类一定要放到Editor目录下,否则无效!!!

    相关文章

      网友评论

          本文标题:第二章 AutoBuild.BuildPackage

          本文链接:https://www.haomeiwen.com/subject/qhlkeqtx.html