默认构建方法
设定构建方法
在工作流文件设定 buildMethod 为本地构建方法,这样云上构建时会使用指定的构建脚本来构建项目。
默认构建方法
如在工作流文件中不指定 buildMethod, 则会使用下面默认的构建方法。
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEditor.Build.Reporting;
using UnityEngine;
namespace TjBuilderAction
{
public static class DefaultBuildTool
{
private static readonly string EmbeddedPreferenceKey = "OpenHarmony SdkUseEmbedded";
private static readonly string DirectoryPreferenceKey = "OpenHarmonySdkRoot";
public static void BuildProject()
{
var textureManagerSettingsPath = Path.Combine(Application.dataPath, "..", "ProjectSettings", "TextureManagerSettings.asset");
if (File.Exists(textureManagerSettingsPath))
{
File.Delete(textureManagerSettingsPath);
}
Debug.Log("Build AutoStreaming Scenes Assetbundles");
BuildAutoStreamingTextures();
BuildAutoStreamingScenes();
if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.WeixinMiniGame)
{
Assembly wxEditorAssembly = null;
Assembly WxEditorAssembly = null;
Assembly instantGameAssembly = null;
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (var assembly in assemblies)
{
if (assembly.GetName().Name == "wx-editor")
{
wxEditorAssembly = assembly;
}
if (assembly.GetName().Name == "WxEditor")
{
WxEditorAssembly = assembly;
}
if (assembly.GetName().Name == "Unity.InstantGame.Editor")
{
instantGameAssembly = assembly;
}
if (wxEditorAssembly != null && WxEditorAssembly != null)
{
break;
}
}
if (wxEditorAssembly != null)
{
try
{
var MethodGetEditorConf = wxEditorAssembly.GetType("WeChatWASM.UnityUtil")?
.GetMethod("GetEditorConf", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
if (MethodGetEditorConf != null)
{
ScriptableObject ObjConf = null;
try
{
ObjConf = MethodGetEditorConf.Invoke(null, new object[] { false }) as ScriptableObject;
}
catch (TargetParameterCountException e)
{
// 支持WXSDK 2024.10.10的改动 https://gitee.com/wechat-minigame/minigame-tuanjie-transform-sdk/commit/a35ef240711145de3c5dde71dc65f1012b594555
ObjConf = MethodGetEditorConf.Invoke(null, null) as ScriptableObject;
}
if (ObjConf != null)
{
var so = new SerializedObject(ObjConf);
so.FindProperty("ProjectConf.DST").stringValue = GetBuildPath();
var argCdn = GetWxCDNUrl();
if (!string.IsNullOrEmpty(argCdn))
{
so.FindProperty("ProjectConf.CDN").stringValue = argCdn;
}
var argAppId = GetWxAppId();
if (!string.IsNullOrEmpty(argAppId))
{
so.FindProperty("ProjectConf.Appid").stringValue = argAppId;
}
so.FindProperty("CompileOptions.Webgl2").boolValue = true;
so.FindProperty("ProjectConf.Orientation").enumValueIndex = 0;
so.ApplyModifiedProperties();
}
}
var MethodDoExport = WxEditorAssembly.GetType("WeChatWASM.WXConvertCore")?
.GetMethod("DoExport", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
if (MethodDoExport != null)
{
Debug.Log("[BuildTool] Start to convert WeixinMiniGame.");
var result1 = MethodDoExport.Invoke(null, new object[] { true });
if ((int)result1 == 0)
{
Debug.Log("[BuildTool Debug] update ui for fix npe");
typeof(EditorStyles).GetField("s_Current", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(null, new EditorStyles());
string firstBundlePath = WxEditorAssembly.GetType("WeChatWASM.WXConvertCore").GetField("FirstBundlePath").GetValue(null)?.ToString();
// 上传首包资源
if (!string.IsNullOrEmpty(firstBundlePath) && File.Exists(firstBundlePath))
{
if (instantGameAssembly != null)
{
var MethodUploadWeChatDataFile = instantGameAssembly.GetType("Unity.InstantGame.IGBuildPipeline").GetMethod("UploadWeChatDataFile", BindingFlags.Static | BindingFlags.Public);
if (MethodUploadWeChatDataFile != null)
{
if ((bool)MethodUploadWeChatDataFile.Invoke(null, new object[] { firstBundlePath }))
{
Debug.Log("[BuildTool] Convert WeixinMiniGame and Upload Resources succeeded.");
if (Application.isBatchMode) EditorApplication.Exit(0);
return;
}
else
{
Debug.LogError("[BuildTool] Upload Resource Failed");
if (Application.isBatchMode) EditorApplication.Exit(-1);
return;
}
}
else
{
Debug.LogError("[BuildTool] MethodUploadWechatDataFile not found");
if (Application.isBatchMode) EditorApplication.Exit(-1);
return;
}
}
else
{
Debug.Log("[BuildTool] Convert WeixinMiniGame succeed");
return;
}
}
else
{
Debug.LogError("Convert Failed");
if (Application.isBatchMode) EditorApplication.Exit(-1);
return;
}
}
}
}
catch (Exception e)
{
Debug.LogError(e);
}
Debug.Log("[BuildTool] Convert WeixinMiniGame failed.");
}
else
{
Debug.Log("[BuildTool] WeixinMiniGame SDK not found.");
}
if (Application.isBatchMode) EditorApplication.Exit(-1);
}
else
{
Debug.Log("[BuildTool] Start to build regular player.");
BuildPlayer();
}
}
static void BuildAutoStreamingScenes()
{
var m = Type.GetType("Unity.AutoStreaming.ASSceneUI,Unity.InstantGame.Editor")?.GetMethod(
"GenerateSceneAssetBundles", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
var m2 = Type.GetType("UnityEditor.AutoStreamingSettings,UnityEditor")?.GetMethod(
"SyncSharedSceneAssets", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
try
{
m.Invoke(null, new object[] { true });
m2.Invoke(null, new object[0]);
}
catch (Exception e)
{
Debug.Log($"Type:{e.GetType()}, Message:{e.Message}, StackTrace:{e.StackTrace}");
Debug.Log($"Type:{e.InnerException?.GetType()}, Message:{e.InnerException?.Message}, StackTrace:{e.InnerException?.StackTrace}");
}
}
static void BuildAutoStreamingTextures()
{
var m = Type.GetType("Unity.AutoStreaming.ASTextureUI,Unity.InstantGame.Editor")?.GetMethod(
"GenerateTextureAssetBundles", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
var m2 = Type.GetType("Unity.AutoStreaming.ASUtilities,Unity.InstantGame.Editor")?.GetMethod(
"GenerateAddressablePathsText", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
var m3 = Type.GetType("UnityEditor.AutoStreamingSettings,UnityEditor")?.GetMethod(
"SyncTextures", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
try
{
m.Invoke(null, new object[] { true });
m2.Invoke(null, new object[0]);
m3.Invoke(null, new object[] { true });
}
catch (Exception e)
{
Debug.Log($"Type:{e.GetType()}, Message:{e.Message}, StackTrace:{e.StackTrace}");
Debug.Log($"Type:{e.InnerException?.GetType()}, Message:{e.InnerException?.Message}, StackTrace:{e.InnerException?.StackTrace}");
}
}
static void BuildPlayer()
{
var output = GetBuildPath();
CheckExportAsProject(output);
CheckBuildPathExist(output);
if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.OpenHarmony)
{
string[] unusedFolder = { "Assets/WX-WASM-SDK-V2" };
foreach (var asset in AssetDatabase.FindAssets("", unusedFolder))
{
var path = AssetDatabase.GUIDToAssetPath(asset);
AssetDatabase.DeleteAsset(path);
}
AssetDatabase.Refresh();
EditorPrefs.SetBool(EmbeddedPreferenceKey, String.IsNullOrEmpty(Environment.GetEnvironmentVariable("HOS_SDK_HOME")));
EditorPrefs.SetString(DirectoryPreferenceKey, Environment.GetEnvironmentVariable("HOS_SDK_HOME"));
UnityEngine.Debug.Log($"{EmbeddedPreferenceKey}: {EditorPrefs.GetBool(EmbeddedPreferenceKey)}");
UnityEngine.Debug.Log($"{DirectoryPreferenceKey}: {EditorPrefs.GetString(DirectoryPreferenceKey)}");
}
BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions
{
scenes = EditorBuildSettings.scenes.Where(scene => scene.enabled).Select(scene => scene.path).ToArray(),
locationPathName = output,
target = EditorUserBuildSettings.activeBuildTarget,
options = BuildOptions.None
};
BuildReport report = BuildPipeline.BuildPlayer(buildPlayerOptions);
BuildSummary summary = report.summary;
if (summary.result == BuildResult.Succeeded)
{
Debug.Log("Build player succeeded.");
EditorApplication.Exit(0);
}
if (summary.result == BuildResult.Failed)
{
Debug.Log("Build player failed.");
EditorApplication.Exit(-1);
}
}
static string GetBuildPath()
{
var path = GetArgValue("customBuildPath");
if (Path.IsPathFullyQualified(path))
{
return path;
}
var ret = Path.Combine(Application.dataPath, "..", "Build", EditorUserBuildSettings.activeBuildTarget.ToString());
if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.StandaloneWindows64)
{
ret += ".exe";
}
else if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android &&
!EditorUserBuildSettings.exportAsGoogleAndroidProject)
{
ret += ".apk";
}
else if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.OpenHarmony &&
!EditorUserBuildSettings.exportAsOpenHarmonyProject)
{
ret += ".hap";
}
return ret;
}
static void CheckExportAsProject(string buildPath)
{
if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android && buildPath.EndsWith(".apk"))
{
EditorUserBuildSettings.exportAsGoogleAndroidProject = false;
}
else
{
EditorUserBuildSettings.exportAsGoogleAndroidProject = true;
}
if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.OpenHarmony && buildPath.EndsWith(".hap"))
{
EditorUserBuildSettings.exportAsOpenHarmonyProject = false;
}
else
{
EditorUserBuildSettings.exportAsOpenHarmonyProject = true;
}
}
static void CheckBuildPathExist(string buildPath)
{
string extName = Path.GetExtension(buildPath);
string outputDir = string.IsNullOrEmpty(extName) ? Path.GetFullPath(buildPath) : Path.GetDirectoryName(buildPath);
if (outputDir != null)
{
if (Directory.Exists(outputDir))
Directory.Delete(outputDir, true);
Directory.CreateDirectory(outputDir);
}
}
static string GetWxCDNUrl()
{
return GetArgValue("WxCDN");
}
static string GetWxAppId()
{
return GetArgValue("WxAppId");
}
static string GetArgValue(string arg)
{
var args = System.Environment.GetCommandLineArgs();
for (var i = 0; i < args.Length; i++)
{
if (args[i].Equals($"-{arg}", StringComparison.OrdinalIgnoreCase) && i < args.Length - 1)
{
var value = args[i + 1];
return value;
}
}
return "";
}
}
}