Unity兼容微信和抖音小游戏

3,210 阅读6分钟

前言

最近在用unity同时接入微信和抖音小游戏时遇到了一些坑, 记录避坑方法

程序集冲突

问题

当项目里同时存在微信和抖音小游戏的unity sdk时, 会有如下报错

image.png wx-runtime-editorttsdk程序集里都有PlayerPrefs, 导致addressables报错, 如果去修改addressables的代码指定PlayerPrefs所在的命名空间或者修改让程序集也条件编译虽然能解决报错, 但侵入式的修改不方便后续维护

解决方案

  1. 在项目根目录下备份微信和抖音小游戏的unity sdk代码
  2. 构建时按需将备份的代码拷贝到项目里, 其中微信小游戏sdk代码路径为Packages/com.qq.weixin.minigame, 抖音小游戏sdk代码路径为Assets/Plugins/ByteGame, 这样同一时间只会存在一个平台的sdk, 让程序集不再冲突

EditorRuntime的宏生效

问题

微信小游戏和抖音小游戏有不同的打包脚本, 而且定义了不同的条件编译宏

Editor/BuildWXMiniGame.cs

#if WEIXINMINIGAME
using WeChatWASM;
...
#endif

Editor/BuildDYMiniGame.cs

#if DOUYINMINIGAME
using StarkSDKTool;
...
#endif

当动态的写入WEIXINMINIGAME或者DOUYINMINIGAME宏后, 打包脚本并不能立即正常运行

解决方案

使用脚本运行两次unity, 第一次写入宏, 第二次执行打包脚本

其他一些注意事项

  • 申请抖音小游戏时需要选择开发引擎为unity, 且后续不能修改, 微信小游戏则不限制引擎类型
  • 抖音小游戏如果想插入js文件需要参考官方文档, 微信小游戏则很自由的可以插入js文件
  • 指定抖音小游戏打包路径, 如果路径的目标文件夹不存在, 则会打包至根目录下的Build文件夹, 不像微信小游戏那样会自动创建目标文件夹

附: unity打包微信和抖音小游戏的核心方法与主要参数

unity打包微信小游戏

核心方法

// 转换小游戏(同步)
WeChatWASM.WXConvertCore.WXExportError result = WeChatWASM.WXConvertCore.DoExport()
if (result == WeChatWASM.WXConvertCore.WXExportError.SUCCEED) {
    UnityEngine.Debug.Log("转换小游戏成功");
} else {
    UnityEngine.Debug.Log("转换小游戏失败: " + e.Message);
}

// 压缩纹理(异步)
    public static async Task<object> CompressText()
    {
        Print("开始压缩纹理");
        var tcs = new TaskCompletionSource<object>();
        WeChatWASM.WXAssetsTextTools.CompressText((result, msg) =>
            {
                if (result)
                {
                    UnityEngine.Debug.Log("压缩纹理成功!");
                    tcs.SetResult(result);
                }
                else
                {
                    UnityEngine.Debug.Log("压缩纹理失败: " + msg);
                    tcs.SetException(new Exception(msg));
                }
            },
            null,
            null,
            false,
            false);
        return await tcs.Task;
    }

主要参数

        // 游戏appid
        WXConvertCore.config.ProjectConf.Appid = "xxx";
        // 导出路径(绝对路径)
        WXConvertCore.config.ProjectConf.DST = "xxx";
        // 启动视频封面图/背景图(相对路径)
        WXConvertCore.config.ProjectConf.bgImageSrc = "xx";
        // 游戏资源CDN
        WXConvertCore.config.ProjectConf.CDN = "";
        // 预下载列表, 多个以分号;隔开
        WXConvertCore.config.ProjectConf.preloadFiles = "";
        // 小游戏项目名
        WXConvertCore.config.ProjectConf.projectName = "";
        // 首包资源加载方式, 0为cdn, 1为包内
        WXConvertCore.config.ProjectConf.assetLoadType = 0;
        // 首包压缩
        WXConvertCore.config.ProjectConf.compressDataPackage = true;
        // 视频url
        WXConvertCore.config.ProjectConf.VideoUrl = "";
        // AB包CDN地址
        WXConvertCore.config.ProjectConf.StreamCDN = "";
        // bundle的hash长度
        WXConvertCore.config.ProjectConf.bundleHashLength = 32;
        // 路径中包含什么标识符表示下载bundle,需要自动缓存
        WXConvertCore.config.ProjectConf.bundlePathIdentifier = "StreamingAssets;";
        // 排除路径下指定类型文件不缓存
        WXConvertCore.config.ProjectConf.bundleExcludeExtensions = "json;";
        // Assets目录对应CDN地址
        WXConvertCore.config.ProjectConf.AssetsUrl = "";
        // 游戏内存大小(MB) UnityHeep预留内存
        WXConvertCore.config.ProjectConf.MemorySize = 512;
        // callmain完成后是否立即隐藏加载封面
        WXConvertCore.config.ProjectConf.HideAfterCallMain = true;
        // 游戏方向
        WXConvertCore.config.ProjectConf.Orientation = 0;
        // 拼接在DATA_CDN和首包资源文件名的路径,用于首包资源没放到DATA_CDN根目录的情况
        WXConvertCore.config.ProjectConf.dataFileSubPrefix = "";
        // 最大缓存容量,单位MB
        WXConvertCore.config.ProjectConf.maxStorage = 200;
        // 清理缓存时默认额外清理的大小,单位Bytes,默认值30MB
        WXConvertCore.config.ProjectConf.defaultReleaseSize = 31457280;
        // 纹理中hash长度
        WXConvertCore.config.ProjectConf.texturesHashLength = 8;
        // 纹理存储路径
        WXConvertCore.config.ProjectConf.texturesPath = "Assets/Textures";
        // 是否缓存纹理
        WXConvertCore.config.ProjectConf.needCacheTextures = true;
        // 加载进度条的宽度,默认240
        WXConvertCore.config.ProjectConf.loadingBarWidth = 240;
        // 是否需要启动时自动检查小游戏是否有新版本
        WXConvertCore.config.ProjectConf.needCheckUpdate = false;
        // 是否禁止开启高性能模式后在不支持的iOS设备上回退为普通模式
        // 注意:不要随意修改,只有开通高性能模式后并确认不回退才修改
        WXConvertCore.config.ProjectConf.disableHighPerformanceFallback = false;
        // IOS限制固定的分辨率,以减少内存,但是会降低游戏画面品质
        // 注意:不要随意修改,默认值为0,0表示不限制
        WXConvertCore.config.ProjectConf.IOSDevicePixelRatio = 0;
        WXConvertCore.config.CompileOptions = new CompileOptions();
        // Development Build
        WXConvertCore.config.CompileOptions.DevelopBuild = false;
        // Autoconnect Profiler
        WXConvertCore.config.CompileOptions.AutoProfile = false;
        // Scripts Only Build
        WXConvertCore.config.CompileOptions.ScriptOnly = false;
        // Il2CppCodeGeneration.OptimizeSize
        WXConvertCore.config.CompileOptions.Il2CppOptimizeSize = true;
        // Profiling Funcs
        WXConvertCore.config.CompileOptions.profilingFuncs = false;
        // WebGL2.0
        WXConvertCore.config.CompileOptions.Webgl2 = false;
        // 首包资源优化
        WXConvertCore.config.CompileOptions.fbslim = true;
        // 是否使用brotli多线程压缩
        WXConvertCore.config.CompileOptions.brotliMT = true;
        // DeleteStreamingAssets
        WXConvertCore.config.CompileOptions.DeleteStreamingAssets = true;
        // ProfilingMemory
        WXConvertCore.config.CompileOptions.ProfilingMemory = false;
        // CleanBuild
        WXConvertCore.config.CompileOptions.CleanBuild = false;
        // CustomNodePath
        WXConvertCore.config.CompileOptions.CustomNodePath = "";
        // 是否显示最佳实践检测弹框
        WXConvertCore.config.CompileOptions.showMonitorSuggestModal = false;
        // 是否显示性能面板
        WXConvertCore.config.CompileOptions.enableProfileStats = false;
        // 是否显示渲染分析日志(develop build才生效)
        WXConvertCore.config.CompileOptions.enableRenderAnalysis = false;
        // iOS高性能模式自动GC间隔(毫秒)
        WXConvertCore.config.CompileOptions.iOSAutoGCInterval = 10000;
        // 是否使用iOS高性能Plus
        WXConvertCore.config.CompileOptions.enableIOSPerformancePlus = true;
        WXConvertCore.config.FontOptions = new FontOptions();
        // 基本汉字
        WXConvertCore.config.FontOptions.CJK_Unified_Ideographs = true;
        // 基本拉丁语(英文大小写、数字、英文标点)
        WXConvertCore.config.FontOptions.C0_Controls_and_Basic_Latin = true;
        // 中文标点符号
        WXConvertCore.config.FontOptions.CJK_Symbols_and_Punctuation = true;
        // 通用标点符号
        WXConvertCore.config.FontOptions.General_Punctuation = true;
        // CJK字母及月份
        WXConvertCore.config.FontOptions.Enclosed_CJK_Letters_and_Months = true;
        // 中文竖排标点
        WXConvertCore.config.FontOptions.Vertical_Forms = true;
        // CJK兼容符号
        WXConvertCore.config.FontOptions.CJK_Compatibility_Forms = true;
        // 杂项符号
        WXConvertCore.config.FontOptions.Miscellaneous_Symbols = true;
        // CJK特殊符号
        WXConvertCore.config.FontOptions.CJK_Compatibility = true;
        // 全角ASCII、全角中英文标点、半宽片假名、半宽平假名、半宽韩文字母
        WXConvertCore.config.FontOptions.Halfwidth_and_Fullwidth_Forms = true;
        // 装饰符号
        WXConvertCore.config.FontOptions.Dingbats = true;
        // 字母式符号
        WXConvertCore.config.FontOptions.Letterlike_Symbols = true;
        // 带圈或括号的字母数字
        WXConvertCore.config.FontOptions.Enclosed_Alphanumerics = true;
        // 数字形式
        WXConvertCore.config.FontOptions.Number_Forms = true;
        // 货币符号
        WXConvertCore.config.FontOptions.Currency_Symbols = true;
        // 箭头
        WXConvertCore.config.FontOptions.Arrows = true;
        // 几何图形
        WXConvertCore.config.FontOptions.Geometric_Shapes = true;
        // 数学运算符号
        WXConvertCore.config.FontOptions.Mathematical_Operators = true;
        // 自定义需要的Unicode字符
        WXConvertCore.config.FontOptions.CustomUnicode = "";
        WXConvertCore.config.SDKOptions = new SDKOptions();
        // 使用好友关系链
        WXConvertCore.config.SDKOptions.UseFriendRelation = false;
        // 使用压缩纹理替换(beta)
        WXConvertCore.config.SDKOptions.UseCompressedTexture = false;
        // 使用社交组件
        WXConvertCore.config.SDKOptions.UseMiniGameChat = false;
        // 是否预载微信系统字体
        WXConvertCore.config.SDKOptions.PreloadWXFont = false;

unity打包抖音小游戏

核心方法

// 转换小游戏(异步)
try {
    string res = await StarkSDKTool.API.BuildManager.Build(StarkSDKTool.Framework.Wasm);
} catch (Exception e) {
    
}

主要参数

        
        // 游戏appid
        StarkSDKTool.StarkBuilderSettings.Instance.appId = "xxx";
        // 打包输出目录, 绝对路径
        StarkSDKTool.StarkBuilderSettings.Instance.webGLOutputDir = "xxx";
        // WebGL模式下音频资源的url​
        StarkSDKTool.StarkBuilderSettings.Instance.wasmResourceUrl = "htt =//";
        // 生成WebGL压缩包的路径​
        // StarkSDKTool.StarkBuilderSettings.Instance.webGLOutputDir = "/Users/hcm-b0552/happy-work/platform-public/unity_mix_demo/Output";
        // 对应WebGL构建面板上的复制音频文件,开启会自动将工程目录中的音频文件以工程目录的结构复制出来
        StarkSDKTool.StarkBuilderSettings.Instance.useByteAudioAPI = false;
        // WebGL模式下预占内存值大小​
        StarkSDKTool.StarkBuilderSettings.Instance.wasmMemorySize = 128;
        // 是否开启WebGL2.0​
        StarkSDKTool.StarkBuilderSettings.Instance.isWebGL2 = false;
        // 是否开启压缩​
        StarkSDKTool.StarkBuilderSettings.Instance.needCompress = true;
        // symbols模式
        StarkSDKTool.StarkBuilderSettings.Instance.symbolMode = WebGLDebugSymbolMode.External;
        StarkSDKTool.StarkBuilderSettings.Instance.profiling = false;
        // 构建选项​
        StarkSDKTool.StarkBuilderSettings.Instance.buildOptions = 0;
        StarkSDKTool.StarkBuilderSettings.Instance.optimizeWebGLMemoryInBackground = true;
        StarkSDKTool.StarkBuilderSettings.Instance.assetBundleFSEnabled = true;
        StarkSDKTool.StarkBuilderSettings.Instance.assetBundleBufferCapacity = 128;
        StarkSDKTool.StarkBuilderSettings.Instance.assetBundleBufferTTL = 5;
        string[] urlCacheList = { "bytedance.com" };
        // 缓存资源域名列表​
        StarkSDKTool.StarkBuilderSettings.Instance.urlCacheList = urlCacheList;
        string[] dontCacheFileNames = { };
        // 构建时不自动缓存的文件​
        StarkSDKTool.StarkBuilderSettings.Instance.dontCacheFileNames = dontCacheFileNames;
        // 是否开启development​
        StarkSDKTool.StarkBuilderSettings.Instance.isDevBuild = false;
        // 是否开启stripEngineCode​
        StarkSDKTool.StarkBuilderSettings.Instance.stripEngineCode = false;
        // 基础apk名称​
        StarkSDKTool.StarkBuilderSettings.Instance.apkFileNameBase = "";
        // 生成apk所在目录​
        StarkSDKTool.StarkBuilderSettings.Instance.apkOutputDir = "";
        // 宿主(调试时的宿主)
        StarkSDKTool.StarkBuilderSettings.Instance.appHost = StarkSDKTool.AppHost.DouYin;
        // 压缩方法​
        StarkSDKTool.StarkBuilderSettings.Instance.compressMethod = StarkSDKTool.CompressMethod.LZ4;
        // runtimeEnv(调试时的版本环境)​
        StarkSDKTool.StarkBuilderSettings.Instance.runtimeEnv = 0;
        // 运行框架​
        StarkSDKTool.StarkBuilderSettings.Instance.framework = StarkSDKTool.Framework.Wasm;
        // cpu架构​
        StarkSDKTool.StarkBuilderSettings.Instance.architecture = StarkSDKTool.AndroidArchitecture.All;
        // 最低安卓版本​
        StarkSDKTool.StarkBuilderSettings.Instance.miniApkVersion = 0;
        // 脚本后端​
        StarkSDKTool.StarkBuilderSettings.Instance.scriptingBackend = 0;
        // Native脚本白名单​
        StarkSDKTool.StarkBuilderSettings.Instance.NativeWhiteListRegex = new List<string> { "com.bytedance.starksdk", "_Backup~" };
        // 发布游戏的版本​
        StarkSDKTool.StarkBuilderSettings.Instance.version = "";
        // 是否开启自动版本号功能​
        StarkSDKTool.StarkBuilderSettings.Instance.autoVersion = false;
        // 发布描述​
        StarkSDKTool.StarkBuilderSettings.Instance.publishDesc = "";
        // 开发者工具的可执行文件路径,Windows下以exe结尾,Mac下以app结尾
        // StarkSDKTool.StarkBuilderSettings.Instance.idePath = "/Applications/抖音开发者工具.app";
        // 游戏的appId​
        StarkSDKTool.StarkBuilderSettings.Instance.appId = "xx07";
        // 生成的webgl zip包的路径(注意:是生成后的)
        StarkSDKTool.StarkBuilderSettings.Instance.webglPackagePath = "xx.zip";
        // 屏幕方向​
        StarkSDKTool.StarkBuilderSettings.Instance.orientation = 0;
        // 胶囊深浅色​
        StarkSDKTool.StarkBuilderSettings.Instance.menuButtonStyle = 0;
        // 发布类型​
        StarkSDKTool.StarkBuilderSettings.Instance.publishType = 0;
        StarkSDKTool.StarkBuilderSettings.Instance.name = "StarkBuilderSetting";
        StarkSDKTool.StarkBuilderSettings.Instance.hideFlags = 0;