2026-03-02 15:46:57 +08:00
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
using UnityEditor;
|
|
|
|
|
|
using UnityEditor.Build;
|
|
|
|
|
|
using UnityEditor.Build.Reporting;
|
|
|
|
|
|
using UnityEditor.SceneManagement;
|
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
|
|
|
|
|
|
namespace WeChatWASM
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// PC高性能小游戏构建预处理器
|
2026-03-02 19:15:34 +08:00
|
|
|
|
/// 负责在构建前向首场景注入 WXPCHPInitScript
|
2026-03-02 15:46:57 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public class PCHPBuildPreProcessor : IPreprocessBuildWithReport
|
|
|
|
|
|
{
|
2026-03-02 19:15:34 +08:00
|
|
|
|
// SDK 脚本名称常量
|
|
|
|
|
|
private const string SDK_CLASS_NAME = "WeChatWASM.WXPCHPInitScript";
|
|
|
|
|
|
private const string SDK_GAMEOBJECT_NAME = "WXPCHPInitScript";
|
|
|
|
|
|
|
2026-03-02 15:46:57 +08:00
|
|
|
|
public int callbackOrder => 0;
|
|
|
|
|
|
|
|
|
|
|
|
public void OnPreprocessBuild(BuildReport report)
|
|
|
|
|
|
{
|
2026-03-02 19:15:34 +08:00
|
|
|
|
Debug.Log("========================================");
|
|
|
|
|
|
Debug.Log("[PC高性能小游戏] PCHPBuildPreProcessor.OnPreprocessBuild 被调用");
|
|
|
|
|
|
Debug.Log("========================================");
|
|
|
|
|
|
|
2026-03-02 15:46:57 +08:00
|
|
|
|
// 只处理 Windows/Mac Standalone 构建
|
|
|
|
|
|
var buildTarget = report.summary.platform;
|
|
|
|
|
|
if (buildTarget != BuildTarget.StandaloneWindows64 &&
|
|
|
|
|
|
buildTarget != BuildTarget.StandaloneOSX)
|
|
|
|
|
|
{
|
2026-03-02 19:15:34 +08:00
|
|
|
|
Debug.LogWarning($"[PC高性能小游戏] 当前平台 {buildTarget} 不是 Windows/Mac,跳过预处理");
|
2026-03-02 15:46:57 +08:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Debug.Log("[PC高性能小游戏] 开始预处理构建...");
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
2026-03-02 19:15:34 +08:00
|
|
|
|
Debug.Log("[PC高性能小游戏] → 步骤1: 检查 WXPCHPInitScript 脚本是否存在");
|
2026-03-02 15:46:57 +08:00
|
|
|
|
EnsureSDKScriptExists();
|
|
|
|
|
|
|
2026-03-02 19:15:34 +08:00
|
|
|
|
Debug.Log("[PC高性能小游戏] → 步骤2: 向首场景注入 SDK GameObject");
|
2026-03-02 15:46:57 +08:00
|
|
|
|
InjectSDKToFirstScene();
|
|
|
|
|
|
|
2026-03-02 19:15:34 +08:00
|
|
|
|
Debug.Log("[PC高性能小游戏] ✅ 预处理完成!");
|
2026-03-02 15:46:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
catch (System.Exception e)
|
|
|
|
|
|
{
|
2026-03-02 19:15:34 +08:00
|
|
|
|
Debug.LogError("========================================");
|
|
|
|
|
|
Debug.LogError($"[PC高性能小游戏] ❌ 预处理失败: {e.Message}\n{e.StackTrace}");
|
|
|
|
|
|
Debug.LogError("========================================");
|
|
|
|
|
|
throw;
|
2026-03-02 15:46:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2026-03-02 19:15:34 +08:00
|
|
|
|
/// 在所有程序集中查找类型
|
2026-03-02 15:46:57 +08:00
|
|
|
|
/// </summary>
|
2026-03-02 19:15:34 +08:00
|
|
|
|
private System.Type FindTypeInAllAssemblies(string typeName)
|
2026-03-02 15:46:57 +08:00
|
|
|
|
{
|
2026-03-02 19:15:34 +08:00
|
|
|
|
foreach (var assembly in System.AppDomain.CurrentDomain.GetAssemblies())
|
2026-03-02 15:46:57 +08:00
|
|
|
|
{
|
2026-03-02 19:15:34 +08:00
|
|
|
|
var type = assembly.GetType(typeName);
|
|
|
|
|
|
if (type != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return type;
|
|
|
|
|
|
}
|
2026-03-02 15:46:57 +08:00
|
|
|
|
}
|
2026-03-02 19:15:34 +08:00
|
|
|
|
return null;
|
|
|
|
|
|
}
|
2026-03-02 15:46:57 +08:00
|
|
|
|
|
2026-03-02 19:15:34 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 确保 WXPCHPInitScript 脚本存在
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private void EnsureSDKScriptExists()
|
|
|
|
|
|
{
|
|
|
|
|
|
var sdkType = FindTypeInAllAssemblies(SDK_CLASS_NAME);
|
|
|
|
|
|
if (sdkType != null)
|
2026-03-02 15:46:57 +08:00
|
|
|
|
{
|
2026-03-02 19:15:34 +08:00
|
|
|
|
Debug.Log($"[PC高性能小游戏] ✅ WXPCHPInitScript 脚本已加载 (程序集: {sdkType.Assembly.GetName().Name})");
|
2026-03-02 15:46:57 +08:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-02 19:15:34 +08:00
|
|
|
|
// 脚本应该在 SDK Runtime 目录,如果找不到说明 SDK 安装有问题
|
|
|
|
|
|
Debug.LogError("[PC高性能小游戏] ❌ 找不到 WXPCHPInitScript 类型");
|
|
|
|
|
|
Debug.LogError("[PC高性能小游戏] 请确保 WX-WASM-SDK-V2 已正确安装");
|
|
|
|
|
|
throw new BuildFailedException("[PC高性能小游戏] 缺少 WXPCHPInitScript 脚本,请检查 SDK 安装");
|
2026-03-02 15:46:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 向第一个启用的场景注入 SDK GameObject
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private void InjectSDKToFirstScene()
|
|
|
|
|
|
{
|
|
|
|
|
|
var firstScenePath = GetFirstEnabledScene();
|
|
|
|
|
|
if (string.IsNullOrEmpty(firstScenePath))
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogWarning("[PC高性能小游戏] 没有找到启用的场景,跳过注入");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var currentScenes = EditorSceneManager.GetSceneManagerSetup();
|
|
|
|
|
|
var scene = EditorSceneManager.OpenScene(firstScenePath, OpenSceneMode.Single);
|
|
|
|
|
|
|
2026-03-02 19:15:34 +08:00
|
|
|
|
// 删除旧的对象(兼容从 EmbeddedAppletSDK 迁移)
|
|
|
|
|
|
var oldSDK = GameObject.Find("EmbeddedAppletSDK");
|
|
|
|
|
|
if (oldSDK != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.Log("[PC高性能小游戏] 删除旧的 EmbeddedAppletSDK 对象");
|
|
|
|
|
|
GameObject.DestroyImmediate(oldSDK);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查是否已存在新的 SDK 对象
|
|
|
|
|
|
var existingSDK = GameObject.Find(SDK_GAMEOBJECT_NAME);
|
2026-03-02 15:46:57 +08:00
|
|
|
|
if (existingSDK != null)
|
|
|
|
|
|
{
|
2026-03-02 19:15:34 +08:00
|
|
|
|
Debug.Log($"[PC高性能小游戏] 场景中已存在 {SDK_GAMEOBJECT_NAME},重新创建");
|
|
|
|
|
|
GameObject.DestroyImmediate(existingSDK);
|
2026-03-02 15:46:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-02 19:15:34 +08:00
|
|
|
|
// 创建 GameObject 并添加组件
|
|
|
|
|
|
var sdkObject = new GameObject(SDK_GAMEOBJECT_NAME);
|
|
|
|
|
|
var sdkType = FindTypeInAllAssemblies(SDK_CLASS_NAME);
|
2026-03-02 15:46:57 +08:00
|
|
|
|
|
|
|
|
|
|
if (sdkType != null)
|
|
|
|
|
|
{
|
2026-03-02 19:15:34 +08:00
|
|
|
|
var assemblyName = sdkType.Assembly.GetName().Name;
|
|
|
|
|
|
Debug.Log($"[PC高性能小游戏] 找到 WXPCHPInitScript,程序集: {assemblyName}");
|
|
|
|
|
|
|
|
|
|
|
|
if (assemblyName.Contains("Editor"))
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogError("[PC高性能小游戏] ❌ WXPCHPInitScript 在 Editor 程序集中!");
|
|
|
|
|
|
GameObject.DestroyImmediate(sdkObject);
|
|
|
|
|
|
throw new BuildFailedException("[PC高性能小游戏] WXPCHPInitScript 必须在 Runtime 程序集");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-02 15:46:57 +08:00
|
|
|
|
sdkObject.AddComponent(sdkType);
|
2026-03-02 19:15:34 +08:00
|
|
|
|
Debug.Log($"[PC高性能小游戏] ✅ 已在 {scene.name} 中创建 {SDK_GAMEOBJECT_NAME} 并添加组件");
|
2026-03-02 15:46:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2026-03-02 19:15:34 +08:00
|
|
|
|
Debug.LogError("[PC高性能小游戏] ❌ 找不到 WXPCHPInitScript 类型");
|
|
|
|
|
|
GameObject.DestroyImmediate(sdkObject);
|
|
|
|
|
|
throw new BuildFailedException("[PC高性能小游戏] 无法找到 WXPCHPInitScript 组件");
|
2026-03-02 15:46:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EditorSceneManager.MarkSceneDirty(scene);
|
|
|
|
|
|
EditorSceneManager.SaveScene(scene);
|
|
|
|
|
|
RestoreScenes(currentScenes);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private string GetFirstEnabledScene()
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var scene in EditorBuildSettings.scenes)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (scene.enabled)
|
|
|
|
|
|
{
|
|
|
|
|
|
return scene.path;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void RestoreScenes(UnityEditor.SceneManagement.SceneSetup[] setup)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (setup != null && setup.Length > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorSceneManager.RestoreSceneManagerSetup(setup);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|