#region Copyright RenGuiYou. All rights reserved. //===================================================== // NeatlyFrameWork // Author: RenGuiyou // Feedback: mailto:750539605@qq.com //===================================================== #endregion using System.IO; using Pandora; using PandoraEditor; using UnityEditor; using UnityEditor.Callbacks; #if UNITY_IOS using UnityEditor.iOS.Xcode; #endif using UnityEngine; using UnityEngine.iOS; namespace NeatlyEditor { public static class NeatlyProjectPacker { private static readonly string NATIVE_PATH = $"{Application.dataPath}/../native"; private static readonly string[] SCENE_LEVELS = {"Assets/Scene/GameMain.unity"}; public static void ExportProject() { SetPlayerSetting(); #if UNITY_ANDROID AndroidExportGradle(); #elif UNITY_IOS IOSExport(); #endif } #region Windows //打包exe public static void WindowsExportExe() { string assetPath = Application.dataPath; string[] names = assetPath.StandardPath().Split('/'); string output = $"{NATIVE_PATH}/package/exe"; string pathName = $"{output}/{names[names.Length - 3]}.exe"; PdrFileUtil.CreateDirectory(output); BuildPipeline.BuildPlayer(SCENE_LEVELS, pathName, BuildTarget.StandaloneWindows, BuildOptions.None); PdrFileUtil.OpenFolder(output); } #endregion #region Android //导出gradle工程 public static void AndroidExportGradle() { string pathName = "Native/android/AndroidProjectTemp"; EditorUserBuildSettings.exportAsGoogleAndroidProject = true; PdrFileUtil.DeleteDirectory(Application.dataPath + "/../" + pathName); BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions(); buildPlayerOptions.scenes = SCENE_LEVELS; buildPlayerOptions.locationPathName = $"{pathName}/{BuildSetting.ProjectBuildSetting.app_name}"; buildPlayerOptions.target = BuildTarget.Android; BuildPipeline.BuildPlayer(buildPlayerOptions); } //打包apk public static void AndroidExportApk() { string appName = BuildSetting.ProjectBuildSetting.app_name; string tempPath = $@"{Application.dataPath}/../Native\android\AndroidProjectTemp\{appName}\unityLibrary\src\main"; string targetPath = $@"{Application.dataPath}/../Native\android\AndroidProject\{appName}\app\src\main"; CopyFile(tempPath, targetPath, "assets"); CopyFile(tempPath, targetPath, "jniLibs"); var builder = PdrCombine.ProjectRoot("Native/builder/unity_android_builder.py"); string args = $@"{Application.dataPath}/../Native\android\AndroidProject\{appName}"; Debug.Log(builder); PdrCMDHelper.ProcessPython($"{builder} {args}"); } private static void CopyFile(string inputPath, string outputPath, string position) { var srcPath = Path.Combine(inputPath, position); var targetPath = Path.Combine(outputPath, position); PdrFileUtil.DeleteDirectory(targetPath); PdrFileUtil.CopyDirectory(srcPath, targetPath); } public static void AndroidBuild() { string projectPath = $"{NATIVE_PATH}/android/AndroidProject"; string outputPath = $"{NATIVE_PATH}/android/AndroidProjectTemp"; string appName = "client"; string args = $"{NATIVE_PATH}/builder/android_builder.py {projectPath} {outputPath} {appName}"; // 调用外部Shell编译 NDebug.Log(projectPath + "/" + appName); PdrCMDHelper.ProcessPython(args); } #endregion public static void IOSExport() { PlayerSettings.iOS.appleEnableAutomaticSigning = false; BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions(); buildPlayerOptions.scenes = SCENE_LEVELS; buildPlayerOptions.locationPathName = $"{NATIVE_PATH}/ios/{PlayerSettings.productName}"; buildPlayerOptions.target = BuildTarget.iOS; BuildPipeline.BuildPlayer(buildPlayerOptions); } #region Setting //设置PlayerSetting public static void SetPlayerSetting() { var setting = BuildSetting.ProjectBuildSetting; BuildTarget target = EditorUserBuildSettings.activeBuildTarget; BuildTargetGroup group = BuildPipeline.GetBuildTargetGroup(target); PlayerSettings.companyName = CommandParam.CompanyName; PlayerSettings.productName = CommandParam.ProductName; PlayerSettings.applicationIdentifier = CommandParam.BundleIdentifier; PlayerSettings.SetScriptingBackend(group, CommandParam.GetScriptingBackend()); PlayerSettings.SetScriptingDefineSymbolsForGroup(group, CommandParam.Symbols); EditorUserBuildSettings.development = CommandParam.Develop; EditorUserBuildSettings.allowDebugging = CommandParam.Develop; PlayerSettings.virtualRealitySplashScreen = GetSplashTexture(); PlayerSettings.SplashScreen.show = false; var tx = AssetDatabase.LoadAssetAtPath($"Assets/App/{CommandParam.Icon}.png"); #if UNITY_ANDROID SetAndroidSetting(); Texture2D[] icons = { tx, tx, tx, tx, tx, tx }; #elif UNITY_IOS SetIOSSetting(); Texture2D[] icons = { tx, tx, tx, tx, tx, tx, tx, tx, tx, tx, tx, tx, tx, tx, tx, tx, tx, tx, tx }; #elif UNITY_STANDALONE_WIN SetWindowsSetting(); Texture2D[] icons = {tx, tx, tx, tx, tx, tx, tx}; #endif PlayerSettings.SetIconsForTargetGroup(group, icons); //不压缩代码 PlayerSettings.stripEngineCode = false; //横竖屏 PlayerSettings.defaultInterfaceOrientation = UIOrientation.AutoRotation; PlayerSettings.allowedAutorotateToPortrait = setting.is_portrait; PlayerSettings.allowedAutorotateToPortraitUpsideDown = setting.is_portrait_upside_down; PlayerSettings.allowedAutorotateToLandscapeLeft = setting.is_landscape_left; PlayerSettings.allowedAutorotateToLandscapeRight = setting.is_landscape_right; //是否调试 EditorUserBuildSettings.connectProfiler = false; } //设置Android private static void SetAndroidSetting() { var setting = BuildSetting.ProjectBuildSetting; PlayerSettings.Android.splashScreenScale = AndroidSplashScreenScale.ScaleToFill; PlayerSettings.Android.minSdkVersion = AndroidSdkVersions.AndroidApiLevel21; PlayerSettings.Android.androidIsGame = true; PlayerSettings.Android.androidTVCompatibility = true; PlayerSettings.Android.targetArchitectures = AndroidArchitecture.ARM64 | AndroidArchitecture.ARMv7; #if UNITY_2019 PlayerSettings.Android.useCustomKeystore = true; #endif PlayerSettings.Android.keystoreName = $"{NATIVE_PATH}/android/key/{setting.android_key_store_name}.keystore"; PlayerSettings.Android.keystorePass = setting.android_key_store_pass; PlayerSettings.Android.keyaliasName = setting.android_key_alias_name; PlayerSettings.Android.keyaliasPass = setting.android_key_alias_pass; EditorUserBuildSettings.androidBuildSubtarget = MobileTextureSubtarget.ETC; EditorUserBuildSettings.androidBuildSystem = AndroidBuildSystem.Gradle; EditorUserBuildSettings.androidBuildType = AndroidBuildType.Release; } //设置IOS private static void SetIOSSetting() { PlayerSettings.iOS.targetDevice = iOSTargetDevice.iPhoneAndiPad; PlayerSettings.iOS.sdkVersion = iOSSdkVersion.DeviceSDK; PlayerSettings.iOS.hideHomeButton = true; PlayerSettings.iOS.requiresFullScreen = true; PlayerSettings.iOS.deferSystemGesturesMode = SystemGestureDeferMode.All; PlayerSettings.SetArchitecture(BuildTargetGroup.iOS, 2); } [PostProcessBuild(999)] public static void OnPostprocessBuild(BuildTarget BuildTarget, string path) { #if UNITY_IOS string projPath = PBXProject.GetPBXProjectPath(path); PBXProject proj = new PBXProject(); proj.ReadFromString(File.ReadAllText(projPath)); // 获取当前项目名字 string target = proj.TargetGuidByName(PBXProject.GetUnityTargetName()); // 对所有的编译配置设置选项 proj.SetBuildProperty(target, "ENABLE_BITCODE", "NO"); // 添加依赖库 proj.AddFrameworkToProject(target, "StoreKit.framework", false); proj.AddFrameworkToProject(target, "GameKit.framework", false); // 保存工程 proj.WriteToFile(projPath); // 修改plist string plistPath = path + "/Info.plist"; PlistDocument plist = new PlistDocument(); plist.ReadFromString(File.ReadAllText(plistPath)); PlistElementDict rootDict = plist.root; // 需要的声明 rootDict.SetString("CFBundleDisplayName", CommandParam.AppName); rootDict.SetString("Privacy - Photo Library Additions Usage Description", ""); rootDict.SetString("NSContactsUsageDescription", ""); // 保存plist plist.WriteToFile (plistPath); #elif UNITY_ANDROID NeatlySymbolsCopy.PostProcessAndroidBuild(path); #endif } private static void SetWindowsSetting() { PlayerSettings.iOS.SetLaunchScreenImage(GetSplashTexture(), iOSLaunchScreenImageType.iPadImage); PlayerSettings.iOS.SetLaunchScreenImage(GetSplashTexture(), iOSLaunchScreenImageType.iPhoneLandscapeImage); PlayerSettings.iOS.SetLaunchScreenImage(GetSplashTexture(), iOSLaunchScreenImageType.iPhonePortraitImage); PlayerSettings.allowFullscreenSwitch = false; PlayerSettings.defaultScreenWidth = 1136; PlayerSettings.defaultScreenHeight = 640; PlayerSettings.fullScreenMode = FullScreenMode.FullScreenWindow; } #endregion private static Texture2D GetSplashTexture() { return AssetDatabase.LoadAssetAtPath("Assets/App/splash.png"); } } } //EditorUtility.DisplayDialog("ICON图标未找到", "路径" + string.Format("Assets/App/{0}.png", ""), "OK");