using System.Collections; using System.Collections.Generic; using UnityEngine; using System; using UnityEditor; using System.IO; using System.Text.RegularExpressions; using System.Text; //using Beebyte.Obfuscator; public class ClientPackage { public static readonly string versionsFilePath = Application.dataPath + "/Editor/VersionConfigs/Versions.txt"; public static readonly string[] baseLevels = new string[] { "Assets/Resources/Scenes/Launch.unity" }; public static string auditOutTime = string.Empty; public static string SDK_PLUGIN_PROJECT { get { return LocalSave.GetString("SDK_PROJECT_PATH"); } set { LocalSave.SetString("SDK_PROJECT_PATH", value); } } public static bool obfuscatorEnabled { get { return LocalSave.GetBool("obfuscatorEnabled", false); } set { LocalSave.SetBool("obfuscatorEnabled", value); } } public static bool includeConfig { get { return LocalSave.GetBool("client_pg_includeConfig", false); } set { LocalSave.SetBool("client_pg_includeConfig", value); } } public static bool includeUI { get { return LocalSave.GetBool("client_pg_includeUI", false); } set { LocalSave.SetBool("client_pg_includeUI", value); } } public static int AssetPrior { get { return LocalSave.GetInt("HalfAssetPrior", 1); } set { LocalSave.SetInt("HalfAssetPrior", value); } } static string THE_2TH_WORLD_SDK_PATH = Application.dataPath + "/Plugins/Android/bin"; static string MANIFEST_PATH = Application.dataPath + "/Plugins/Android/AndroidManifest.xml"; static string iOS_PLUGIN_PATH = Application.dataPath + "/Plugins/iOS/Channel"; static string File_baseProjectTemplate = Application.dataPath + "/Plugins/Android/baseProjectTemplate.gradle"; static string File_google_services = Application.dataPath + "/Plugins/Android/google-services.json"; static string File_gradleTemplate = Application.dataPath + "/Plugins/Android/gradleTemplate.properties"; static string File_LauncherManifest = Application.dataPath + "/Plugins/Android/LauncherManifest.xml"; static string File_launcherTemplate = Application.dataPath + "/Plugins/Android/launcherTemplate.gradle"; static string File_mainTemplate = Application.dataPath + "/Plugins/Android/mainTemplate.gradle"; static string File_deps = Application.dataPath + "/Plugins/Android/deps.gradle"; static string File_settingGradle = Application.dataPath + "/Plugins/Android/settingsTemplate.gradle"; static string File_huawei_services = Application.dataPath + "/Plugins/Android/agconnect-services.json"; /// /// 打包 /// /// 整合sdk路径 /// _assetBundle的资源路径,默认在项目目录下的 AssetBundles/android /// 打包完成后的输出路径 /// 渠道id,可打多个包,用|分割 /// 打包序序号,用于标识名称 /// 是否为开发版 /// ios打包导出xcode工程模式,Append和Replace public static void BuildPublishers(string _sdkPath, string _assetBundlePath, string _output, string _publisherString, int _buildIndex, bool _development, bool _replace) { var publisherIds = new List(); var tempStrings = _publisherString.Split(StringUtility.splitSeparator, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < tempStrings.Length; i++) { var temp = tempStrings[i]; var matches = Regex.Matches(temp, "\\d+"); switch (matches.Count) { case 1: var id = int.Parse(matches[0].Value); publisherIds.Add(id.ToString()); break; case 2: var min = int.Parse(matches[0].Value); var max = int.Parse(matches[1].Value); for (int j = min; j <= max; j++) { publisherIds.Add(j.ToString()); } break; } } var smallPackages = new List(); var halfPackages = new List(); var bigPackages = new List(); for (int i = 0; i < publisherIds.Count; i++) { try { var publisher = publisherIds[i]; var versionName = string.Empty; var versionConfig = GetVersionConfig(publisher, out versionName); switch (versionConfig.assetAccess) { case InstalledAsset.NullAsset: smallPackages.Add(publisher); break; case InstalledAsset.HalfAsset: halfPackages.Add(publisher); break; case InstalledAsset.FullAsset: case InstalledAsset.IngoreDownLoad: bigPackages.Add(publisher); break; } } catch (Exception ex) { Debug.Log(ex); } } if (Directory.Exists(ResourcesPath.Instance.StreamingAssetPath)) { Directory.Delete(ResourcesPath.Instance.StreamingAssetPath, true); } if (smallPackages.Count > 0) { var files = new List(); var builtInFiles = new List(); FileExtersion.GetAllDirectoryFileInfos(_assetBundlePath, files); foreach (var file in files) { var fileName = Path.GetFileName(file.FullName); if (file.FullName.Contains("builtin")) { builtInFiles.Add(file); continue; } } var totalCount = builtInFiles.Count; var completeCount = 0; foreach (var item in builtInFiles) { var extension = Path.GetExtension(item.FullName); if (extension == ".meta") { continue; } var relativePath = FileExtersion.GetFileRelativePath(_assetBundlePath, item.FullName); var to = StringUtility.Contact(ResourcesPath.Instance.StreamingAssetPath, relativePath); var directory = Path.GetDirectoryName(to); if (!Directory.Exists(directory)) { Directory.CreateDirectory(directory); } File.Copy(item.FullName, to, true); completeCount++; } EditorUtility.ClearProgressBar(); for (int i = 0; i < smallPackages.Count; i++) { #if UNITY_ANDROID BuildApk(_sdkPath, _output, smallPackages[i], _buildIndex, _development); #elif UNITY_IOS BuildIpa(_sdkPath, smallPackages[i], _buildIndex, _replace); #endif } } if (halfPackages.Count > 0) { PriorBundleConfig.LazyInit(); var fromFiles = new List(); FileExtersion.GetAllDirectoryFileInfos(_assetBundlePath, fromFiles); var excludeFileFullNames = new List(); var tempFiles = new List(); FileExtersion.GetAllDirectoryFileInfos(StringUtility.Contact(_assetBundlePath, "/hero"), tempFiles); foreach (var file in tempFiles) { var extersion = Path.GetExtension(file.FullName); var fileName = Path.GetFileNameWithoutExtension(file.FullName); var prior = PriorBundleConfig.GetAssetPrior(AssetVersion.AssetCategory.Mob, AssetVersionUtility.DecodeFileName(fileName)); if (prior > AssetPrior) { excludeFileFullNames.Add(file.FullName); } } tempFiles.Clear(); FileExtersion.GetAllDirectoryFileInfos(StringUtility.Contact(_assetBundlePath, "/maps"), tempFiles); foreach (var file in tempFiles) { var extersion = Path.GetExtension(file.FullName); var fileName = Path.GetFileNameWithoutExtension(file.FullName); var prior = PriorBundleConfig.GetAssetPrior(AssetVersion.AssetCategory.Scene, AssetVersionUtility.DecodeFileName(fileName)); if (prior > AssetPrior) { excludeFileFullNames.Add(file.FullName); } } tempFiles.Clear(); FileExtersion.GetAllDirectoryFileInfos(StringUtility.Contact(_assetBundlePath, "/audio"), tempFiles); foreach (var file in tempFiles) { var extersion = Path.GetExtension(file.FullName); var fileName = Path.GetFileNameWithoutExtension(file.FullName); var prior = PriorBundleConfig.GetAssetPrior(AssetVersion.AssetCategory.Audio, AssetVersionUtility.DecodeFileName(fileName)); if (prior > AssetPrior) { excludeFileFullNames.Add(file.FullName); } } tempFiles.Clear(); FileExtersion.GetAllDirectoryFileInfos(StringUtility.Contact(_assetBundlePath, "/uieffect"), tempFiles); foreach (var file in tempFiles) { var extersion = Path.GetExtension(file.FullName); var fileName = Path.GetFileNameWithoutExtension(file.FullName); var prior = PriorBundleConfig.GetAssetPrior(AssetVersion.AssetCategory.Effect, AssetVersionUtility.DecodeFileName(fileName)); if (prior > AssetPrior) { excludeFileFullNames.Add(file.FullName); } } //剔除视频资源 tempFiles.Clear(); var videoPath = StringUtility.Contact(_assetBundlePath, "/video"); if (File.Exists(videoPath)) { FileExtersion.GetAllDirectoryFileInfos(StringUtility.Contact(_assetBundlePath, "/video"), tempFiles); foreach (var file in tempFiles) { var extersion = Path.GetExtension(file.FullName); var fileName = Path.GetFileNameWithoutExtension(file.FullName); var prior = PriorBundleConfig.GetAssetPrior(AssetVersion.AssetCategory.Video, AssetVersionUtility.DecodeFileName(fileName)); if (prior > AssetPrior) { excludeFileFullNames.Add(file.FullName); } } } //剔除表资源 if (!includeConfig) { tempFiles.Clear(); FileExtersion.GetAllDirectoryFileInfos(StringUtility.Contact(_assetBundlePath, "/config"), tempFiles); foreach (var file in tempFiles) { excludeFileFullNames.Add(file.FullName); } } //剔除UI资源 //tempFiles.Clear(); //FileExtersion.GetAllDirectoryFileInfos(StringUtility.Contact(_assetBundlePath, "/ui/sprite"), tempFiles); //foreach (var file in tempFiles) //{ // var fileName = Path.GetFileName(file.FullName); // if (fileName == "loadingbg") // { // excludeFileFullNames.Add(file.FullName); // } //} if (!includeUI) { tempFiles.Clear(); FileExtersion.GetAllDirectoryFileInfos(StringUtility.Contact(_assetBundlePath, "/ui"), tempFiles); foreach (var file in tempFiles) { excludeFileFullNames.Add(file.FullName); } } else { #if !UNITY_IOS //剔除UI资源 tempFiles.Clear(); FileExtersion.GetAllDirectoryFileInfos(StringUtility.Contact(_assetBundlePath, "/ui"), tempFiles); foreach (var file in tempFiles) { var extersion = Path.GetExtension(file.FullName); var fileName = Path.GetFileNameWithoutExtension(file.FullName); var prior = PriorBundleConfig.GetAssetPrior(AssetVersion.AssetCategory.UI, fileName); if (prior > AssetPrior) { excludeFileFullNames.Add(file.FullName); } } #endif } for (int i = fromFiles.Count - 1; i >= 0; i--) { var item = fromFiles[i]; if (excludeFileFullNames.Contains(item.FullName)) { fromFiles.RemoveAt(i); } } var totalCount = fromFiles.Count; var completeCount = 0; foreach (var item in fromFiles) { var relativePath = FileExtersion.GetFileRelativePath(_assetBundlePath, item.FullName); var to = StringUtility.Contact(ResourcesPath.Instance.StreamingAssetPath, relativePath); if (relativePath.StartsWith("patch"))//不包含meta文件和补丁 continue; var directory = Path.GetDirectoryName(to); if (!Directory.Exists(directory)) Directory.CreateDirectory(directory); var extension = Path.GetExtension(item.FullName); if (extension == ".meta") continue; File.Copy(item.FullName, to, true); completeCount++; } EditorUtility.ClearProgressBar(); for (int i = 0; i < halfPackages.Count; i++) { #if UNITY_ANDROID BuildApk(_sdkPath, _output, halfPackages[i], _buildIndex, _development); #elif UNITY_IOS BuildIpa(_sdkPath, halfPackages[i], _buildIndex, _replace); #endif } } if (bigPackages.Count > 0) { var fromFiles = new List(); FileExtersion.GetAllDirectoryFileInfos(_assetBundlePath, fromFiles); var totalCount = fromFiles.Count; var completeCount = 0; foreach (var item in fromFiles) { var relativePath = FileExtersion.GetFileRelativePath(_assetBundlePath, item.FullName); var to = StringUtility.Contact(ResourcesPath.Instance.StreamingAssetPath, relativePath); if (relativePath.StartsWith("patch"))//不包含meta文件和补丁 continue; var directory = Path.GetDirectoryName(to); if (!Directory.Exists(directory)) Directory.CreateDirectory(directory); var extension = Path.GetExtension(item.FullName); if (extension == ".meta") continue; File.Copy(item.FullName, to, true); completeCount++; } for (int i = 0; i < bigPackages.Count; i++) { #if UNITY_ANDROID BuildApk(_sdkPath, _output, bigPackages[i], _buildIndex, _development); #elif UNITY_IOS BuildIpa(_sdkPath, bigPackages[i], _buildIndex, _replace); #endif } } } public static void BuildApk(string _sdkPath, string _output, string _publisher, int _buildIndex, bool _development) { PreBuild(_publisher, _buildIndex); var auditTimeFile = StringUtility.Contact(Application.dataPath, Path.DirectorySeparatorChar, "Resources/Config/AuditTime.txt"); if (File.Exists(auditTimeFile)) { File.Delete(auditTimeFile); } var versionName = string.Empty; var versionConfig = GetVersionConfig(_publisher, out versionName); var versionConfigCSpath = Application.dataPath + "/Scripts/System/ClientVersion/VersionConfig.cs"; var text = File.ReadAllText(versionConfigCSpath); if (text.Contains("VERSION_ALTERNATIVE")) { var pattern = "VERSION_ALTERNATIVE = \".*\""; text = Regex.Replace(text, pattern, StringUtility.Contact("VERSION_ALTERNATIVE = ", "\"", versionConfig.m_Version, "\"")); bool encoderShouldEmitUTF8Identifier = true; bool throwOnInvalidBytes = false; UTF8Encoding encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier, throwOnInvalidBytes); bool append = false; StreamWriter streamWriter = new StreamWriter(versionConfigCSpath, append, encoding); streamWriter.Write(text); streamWriter.Close(); AssetDatabase.ImportAsset(versionConfigCSpath); } // 针对某一些打包的特殊性, 这里特指依赖的第三方库含有资源的问题 // 这里对有这种特型的渠道的sdk在打包的时候差异化gradle文件 // 更名原有文件 // string _gradleTemplateUrl = EditorApplication.applicationContentsPath + "/PlaybackEngines/AndroidPlayer/Tools/GradleTemplates/"; // string _gradleFileUrl = _gradleTemplateUrl + "mainTemplate.gradle"; // string _diffGradleFileUrl = StringUtility.Contact(_sdkPath, "/GradleDiff/", versionConfig.appId, "/mainTemplate.gradle"); // FileInfo _fileInfo = new FileInfo(_diffGradleFileUrl); // if (!_fileInfo.Exists) // { // EditorUtility.DisplayDialog("警告", "Gradle模式需要配置差异文件,但是没有找到该文件: " + _diffGradleFileUrl, "@Hale"); // return; // } // _fileInfo.CopyTo(_gradleFileUrl, true); // 移动配置文件至打包工作目录中 var keystorePath = Application.dataPath + "/Editor/Keystore/" + versionConfig.keystoreFileName + ".keystore"; if (!File.Exists(keystorePath)) { Debug.LogError("签名文件不存在"); return; } PlayerSettings.Android.keystoreName = keystorePath; PlayerSettings.Android.keystorePass = versionConfig.keystorePassword; PlayerSettings.Android.keyaliasName = versionConfig.keystoreAlias; PlayerSettings.Android.keyaliasPass = versionConfig.keystoreAliasPassword; // PlayerSettings.Android.targetSdkVersion = AndroidSdkVersions.AndroidApiLevel22; PlayerSettings.Android.bundleVersionCode = VersionConfig.GetVersionNumber(versionConfig.version); PlayerSettings.enableInternalProfiler = _development; //删除原sdk文件 if (Directory.Exists(THE_2TH_WORLD_SDK_PATH)) Directory.Delete(THE_2TH_WORLD_SDK_PATH, true); if (File.Exists(MANIFEST_PATH)) File.Delete(MANIFEST_PATH); if (File.Exists(File_baseProjectTemplate)) File.Delete(File_baseProjectTemplate); if (File.Exists(File_google_services)) File.Delete(File_google_services); if (File.Exists(File_gradleTemplate)) File.Delete(File_gradleTemplate); if (File.Exists(File_LauncherManifest)) File.Delete(File_LauncherManifest); if (File.Exists(File_launcherTemplate)) File.Delete(File_launcherTemplate); if (File.Exists(File_mainTemplate)) File.Delete(File_mainTemplate); if (File.Exists(File_deps)) File.Delete(File_deps); if (File.Exists(File_huawei_services)) File.Delete(File_huawei_services); if (File.Exists(File_settingGradle)) File.Delete(File_settingGradle); var variant = _development ? "debug" : "release"; string channelSdkPath; string copySdkFile; channelSdkPath = StringUtility.Contact(_sdkPath, "/Channel/Android/", versionConfig.sdkFileName, "/", variant); copySdkFile = StringUtility.Contact(_sdkPath, "/Channel/Android/", versionConfig.sdkFileName, "/AndroidManifest.xml"); File.Copy(copySdkFile, MANIFEST_PATH); copySdkFile = StringUtility.Contact(_sdkPath, "/Channel/Android/", versionConfig.sdkFileName, "/baseProjectTemplate.gradle"); File.Copy(copySdkFile, File_baseProjectTemplate); copySdkFile = StringUtility.Contact(_sdkPath, "/Channel/Android/", versionConfig.sdkFileName, "/deps.gradle"); File.Copy(copySdkFile, File_deps); copySdkFile = StringUtility.Contact(_sdkPath, "/Channel/Android/", versionConfig.sdkFileName, "/google-services.json"); File.Copy(copySdkFile, File_google_services); copySdkFile = StringUtility.Contact(_sdkPath, "/Channel/Android/", versionConfig.sdkFileName, "/gradleTemplate.properties"); File.Copy(copySdkFile, File_gradleTemplate); //copySdkFile = StringUtility.Contact(_sdkPath, "/Channel/Android/", versionConfig.appId, "/LauncherManifest.xml"); //File.Copy(copySdkFile, File_LauncherManifest); copySdkFile = StringUtility.Contact(_sdkPath, "/Channel/Android/", versionConfig.sdkFileName, "/launcherTemplate.gradle"); File.Copy(copySdkFile, File_launcherTemplate); copySdkFile = StringUtility.Contact(_sdkPath, "/Channel/Android/", versionConfig.sdkFileName, "/mainTemplate.gradle"); File.Copy(copySdkFile, File_mainTemplate); copySdkFile = StringUtility.Contact(_sdkPath, "/Channel/Android/", versionConfig.sdkFileName, "/settingsTemplate.gradle"); File.Copy(copySdkFile, File_settingGradle); if (versionConfig.sdkFileName == "hyyngame_huawei") { copySdkFile = StringUtility.Contact(_sdkPath, "/Channel/Android/", versionConfig.sdkFileName, "/agconnect-services.json"); File.Copy(copySdkFile, File_huawei_services); } Debug.LogFormat("Android 清单等文件拷贝成功"); if (Directory.Exists(channelSdkPath)) { FileExtersion.DirectoryCopy(channelSdkPath, THE_2TH_WORLD_SDK_PATH); Debug.LogFormat("执行Android 渠道SDK 文件拷贝,from:{0};to:{1}", channelSdkPath, THE_2TH_WORLD_SDK_PATH); } else { Debug.LogFormat("Android 渠道SDK文件不存在,{0}", channelSdkPath); return; } //var option = AssetDatabase.LoadAssetAtPath("Assets/Editor/Beebyte/Obfuscator/ObfuscatorOptions.asset"); //if (option != null) //{ // option.enabled = obfuscatorEnabled; // EditorUtility.SetDirty(option); //} AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); if (_development) { var apkName = StringUtility.Contact(_output, "/", versionName, "_", versionConfig.clientPackageFlag, "_v", versionConfig.m_Version, "_", _buildIndex, "_development.apk"); BuildPipeline.BuildPlayer(baseLevels, apkName, BuildTarget.Android, BuildOptions.Development | BuildOptions.ConnectWithProfiler | BuildOptions.AllowDebugging); } else { string apkName; if (EditorUserBuildSettings.buildAppBundle) { Debug.Log("勾选了 Build App Bundle (Google Play) 打包aab"); apkName = StringUtility.Contact(_output, "/", versionName, "_", versionConfig.clientPackageFlag, "_v", versionConfig.m_Version, "_", _buildIndex, ".aab"); } else { Debug.Log("没有勾选 Build App Bundle (Google Play) 打包apk"); apkName = StringUtility.Contact(_output, "/", versionName, "_", versionConfig.clientPackageFlag, "_v", versionConfig.m_Version, "_", _buildIndex, ".apk"); } BuildPipeline.BuildPlayer(baseLevels, apkName, BuildTarget.Android, BuildOptions.None); } } public static VersionConfig versionConfig1 = null; public static void BuildIpa(string _sdkPath, string _publisher, int _buildIndex, bool _replace) { PreBuild(_publisher, _buildIndex); var versionName = string.Empty; versionConfig1 = GetVersionConfig(_publisher, out versionName); if (Directory.Exists(iOS_PLUGIN_PATH)) { Directory.Delete(iOS_PLUGIN_PATH, true); } if (versionConfig1.sdkFileName.Trim().Length != 0) { FileExtersion.DirectoryCopy(StringUtility.Contact(_sdkPath, "/Channel/iOS/", versionConfig1.sdkFileName, "/Plugins"), iOS_PLUGIN_PATH); } else { FileExtersion.DirectoryCopy(StringUtility.Contact(_sdkPath, "/Channel/iOS/", versionConfig1.appId, "/Plugins"), iOS_PLUGIN_PATH); } DateTime outTime; var correct = DateTime.TryParse(auditOutTime, out outTime); var directory = Application.dataPath + Path.DirectorySeparatorChar + "Resources/Config"; if (!Directory.Exists(directory)) { Directory.CreateDirectory(directory); } File.WriteAllText(Application.dataPath + Path.DirectorySeparatorChar + "Resources/Config/AuditTime.txt", correct ? auditOutTime : ""); //var option = AssetDatabase.LoadAssetAtPath("Assets/Editor/Beebyte/Obfuscator/ObfuscatorOptions.asset"); //if (option != null) //{ // option.enabled = obfuscatorEnabled; // EditorUtility.SetDirty(option); //} AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); PlayerSettings.iOS.buildNumber = VersionConfig.Get().buildIndex.ToString(); PlayerSettings.iOS.appleDeveloperTeamID = VersionConfig.Get().appleDeveloperTeamID; #if UNITY_IOS if (_replace) { XCodeProjectMod.BuildIOSProject_Replace(); } else { XCodeProjectMod.BuildIOSProject_Append(); } #endif } //随包安装的资源不同平台不一定可以获取FileInfo,所以需要下载一个文件来获取资源的MD5信息 //该文件在打包时生成 记录随包的所有资源的信息 //该文件记录的资源在包中肯定存在,所以不用去取指定的资源文件获得FileInfo 计算MD5 //通过文件和AssetsVersion.txt的文件做比较,来判断是否需要下载资源 //logicbytes.txt 包含元数据和代码 如果不随包也要处理 static void MakePackageMD5File() { var fileInfos = new List(); FileExtersion.GetAllDirectoryFileInfos(ResourcesPath.Instance.StreamingAssetPath, fileInfos); AssetsVersionCmpMaker.WriteAssetsVersionFile(ResourcesPath.Instance.StreamingAssetPath, fileInfos); Debug.Log("--生成AssetsVersionCmp.txt文件完毕"); } private static void PreBuild(string _publisher, int _buildIndex) { MakePackageMD5File(); var newVersionConfigPath = StringUtility.Contact("Assets/Resources/VersionConfig", ".asset"); var versionName = string.Empty; var fromVersionConfig = GetVersionConfig(_publisher, out versionName); var newVersionConfig = ScriptableObject.CreateInstance(); if (File.Exists(newVersionConfigPath)) { AssetDatabase.DeleteAsset(newVersionConfigPath); } VersionConfig.Copy(fromVersionConfig, newVersionConfig); newVersionConfig.buildTime = DateTime.Now.ToString("yy/MM/dd--HH:mm"); newVersionConfig.buildIndex = _buildIndex; if (File.Exists(Application.dataPath + "/Resources/Game.txt")) { File.Delete(Application.dataPath + "/Resources/Game.txt"); } File.WriteAllText(Application.dataPath + "/Resources/Game.txt", GetGameId(_publisher)); AssetDatabase.CreateAsset(newVersionConfig, newVersionConfigPath); EditorUtility.SetDirty(newVersionConfig); //生成VersionConfigEx.txt 提供给AOT启动时使用 var json = JsonUtility.ToJson(newVersionConfig); string versionConfigExFile = Application.dataPath + "/Resources/VersionConfigEx.txt"; if (File.Exists(versionConfigExFile)) { File.Delete(versionConfigExFile); } File.WriteAllText(versionConfigExFile, json); SetIconAndSplashImage(versionName); //SetCreateRoleAnimation(); PlayerSettings.companyName = "xmsw"; PlayerSettings.productName = newVersionConfig.productName; PlayerSettings.applicationIdentifier = newVersionConfig.bundleIdentifier; PlayerSettings.defaultInterfaceOrientation = UIOrientation.AutoRotation; PlayerSettings.allowedAutorotateToLandscapeLeft = true; PlayerSettings.allowedAutorotateToLandscapeRight = true; PlayerSettings.allowedAutorotateToPortrait = false; PlayerSettings.allowedAutorotateToPortraitUpsideDown = false; PlayerSettings.bundleVersion = VersionConfig.GetVersionNumber(newVersionConfig.version).ToString(); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } public static VersionConfig GetVersionConfig(string _publisher, out string _versionName) { var lines = File.ReadAllLines(versionsFilePath); for (int i = 2; i < lines.Length; i++) { var line = lines[i]; var lineStrings = line.Split('\t'); if (lineStrings[0] == _publisher) { var config = new VersionConfig(); config.Read(line); _versionName = lineStrings[1]; if (!string.IsNullOrEmpty(lineStrings[24])) _versionName = lineStrings[24]; return config; } } _versionName = string.Empty; return null; } static string GetGameId(string _publisher) { var lines = File.ReadAllLines(versionsFilePath); for (int i = 2; i < lines.Length; i++) { var line = lines[i]; var lineStrings = line.Split('\t'); if (lineStrings[0] == _publisher) { return lineStrings[7]; } } return "xbqy"; } static void SetIconAndSplashImage(string _versionName) { var buildTarget = GetBuildTarget(); var texture = AssetDatabase.LoadAssetAtPath(StringUtility.Contact("Assets/Editor/Logo/", _versionName, "/Icon.png")); var iconSizes = PlayerSettings.GetIconSizesForTargetGroup(buildTarget); var icons = new Texture2D[iconSizes.Length]; for (int i = 0; i < iconSizes.Length; i++) { icons[i] = texture; } PlayerSettings.SetIconsForTargetGroup(buildTarget, icons); PlayerSettings.SplashScreen.show = false; PlayerSettings.SplashScreen.showUnityLogo = false; PlayerSettings.SplashScreen.unityLogoStyle = PlayerSettings.SplashScreen.UnityLogoStyle.LightOnDark; var splashImage = AssetDatabase.LoadAssetAtPath(StringUtility.Contact("Assets/Editor/Logo/", _versionName, "/SplashImage.png")); var splashScreenLogo = PlayerSettings.SplashScreenLogo.Create(3, splashImage); PlayerSettings.SplashScreen.logos = new PlayerSettings.SplashScreenLogo[] { splashScreenLogo }; if (buildTarget == BuildTargetGroup.Android) { var projectSettings = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/ProjectSettings.asset")[0]); var splashImageSetting = projectSettings.FindProperty("androidSplashScreen"); splashImageSetting.objectReferenceValue = splashImage.texture; projectSettings.ApplyModifiedProperties(); PlayerSettings.Android.splashScreenScale = AndroidSplashScreenScale.ScaleToFill; } } public static void SetCreateRoleAnimation() { var from = "Assets/Editor/Video/CreateRoleMovie.mp4"; var to = "Assets/StreamingAssets/CreateRoleMovie.mp4"; if (!Directory.Exists(Application.dataPath + "StreamingAssets")) { Directory.CreateDirectory(Application.dataPath + "StreamingAssets"); } if (AssetDatabase.LoadAssetAtPath(to) == null) { AssetDatabase.CopyAsset(from, to); } } static BuildTargetGroup GetBuildTarget() { #if UNITY_ANDROID return BuildTargetGroup.Android; #elif UNITY_IOS return BuildTargetGroup.iOS; #else return BuildTargetGroup.Standalone; #endif } }