diff --git a/CHANGELOG.md b/CHANGELOG.md index 53d64d0a4..61b40d7ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,23 +6,6 @@ Removed - 删除功能/接口 Fixed - 修复问题 Others - 其他 --> -## 2026-1-13 v0.1.31 【普通更新】 -### Fixed -* 普通:修复glx模式下 createVideo underGameView为true 黑屏的问题 -* 普通:修复build profile在团结1.6之后的导出问题 - -## 2025-11-6 v0.1.30 【重要更新】 -### Feature -* 重要:EmscriptenGLX支持微信压缩纹理 -* 普通:EmscriptenGLX支持Android glReadpixels -* 普通:EmscriptenGLX优化Android CPU与功耗 -* 普通:Metal高帧率下功耗优化 -* 普通:团结引擎buildprofile支持 -### Fixed -* 重要:Metal编码库batch size修复 -* 普通:PageManager相关问题修复 -* 普通:iOS18的微信字体修复 - ## 2025-9-8 v0.1.29 【重要更新】 ### Feature * 普通:本地缓存存在时,UnityWebRequest支持同步方式(API:wx.SetSyncReadCacheEnabled)以加快读取速度 diff --git a/Editor/WXConvertCore.cs b/Editor/WXConvertCore.cs index b43838284..08f39476d 100644 --- a/Editor/WXConvertCore.cs +++ b/Editor/WXConvertCore.cs @@ -34,7 +34,14 @@ namespace WeChatWASM if(UnityUtil.GetEngineVersion() == UnityUtil.EngineVersion.Tuanjie) { var absolutePath = Path.GetFullPath("Packages/com.qq.weixin.minigame/WebGLTemplates/WXTemplate2022TJ"); - PlayerSettings.WeixinMiniGame.template = $"PATH:{absolutePath}"; + if (!Directory.Exists(absolutePath)) + { + PlayerSettings.WeixinMiniGame.template = $"{templateHeader}WXTemplate2022TJ"; + } + else + { + PlayerSettings.WeixinMiniGame.template = $"PATH:{absolutePath}"; + } } else { @@ -421,24 +428,24 @@ namespace WeChatWASM bool showEnableGLX2022Plugin = config.CompileOptions.enableEmscriptenGLX && IsCompatibleWithUnity202203OrNewer(); var glx2022Importer = AssetImporter.GetAtPath(glLibs[0]) as PluginImporter; - #if PLATFORM_WEIXINMINIGAME +#if PLATFORM_WEIXINMINIGAME glx2022Importer.SetCompatibleWithPlatform(BuildTarget.WeixinMiniGame, showEnableGLX2022Plugin); - #else - glx2022Importer.SetCompatibleWithPlatform(BuildTarget.WebGL, showEnableGLX2022Plugin); - #endif +#else + glx2022Importer.SetCompatibleWithPlatform(BuildTarget.WebGL, showEnableGLX2022Plugin); +#endif SetPluginCompatibilityByModifyingMetadataFile(glLibs[0], showEnableGLX2022Plugin); } - + { // unity2021 lib引入 bool showEnableGLX2021Plugin = config.CompileOptions.enableEmscriptenGLX && IsCompatibleWithUnity202102To202203(); var glx2021Importer = AssetImporter.GetAtPath(glLibs[1]) as PluginImporter; - #if PLATFORM_WEIXINMINIGAME +#if PLATFORM_WEIXINMINIGAME glx2021Importer.SetCompatibleWithPlatform(BuildTarget.WeixinMiniGame, showEnableGLX2021Plugin); - #else - glx2021Importer.SetCompatibleWithPlatform(BuildTarget.WebGL, showEnableGLX2021Plugin); - #endif +#else + glx2021Importer.SetCompatibleWithPlatform(BuildTarget.WebGL, showEnableGLX2021Plugin); +#endif SetPluginCompatibilityByModifyingMetadataFile(glLibs[1], showEnableGLX2021Plugin); } @@ -966,7 +973,7 @@ namespace WeChatWASM { new Rule() { - old = "if (GameGlobal.unityNamespace.enableProfileStats)", + old = "if (GameGlobal.unityNamespace.enableProfileStats)", newStr = "if (GameGlobal.unityNamespace.enableProfileStats || (typeof GameGlobal.manager.getWXAppCheatMonitor === 'function' && GameGlobal.manager.getWXAppCheatMonitor().shouldForceShowPerfMonitor()))" } }; diff --git a/Editor/WXPluginVersion.cs b/Editor/WXPluginVersion.cs index e9d555a4d..d554807d0 100644 --- a/Editor/WXPluginVersion.cs +++ b/Editor/WXPluginVersion.cs @@ -2,7 +2,7 @@ namespace WeChatWASM { public class WXPluginVersion { - public static string pluginVersion = "202601131148"; // 这一行不要改他,导出的时候会自动替换 + public static string pluginVersion = "202602051314"; // 这一行不要改他,导出的时候会自动替换 } public class WXPluginConf diff --git a/Editor/wx-editor.dll b/Editor/wx-editor.dll index 2c7b37d3c..1125b813b 100644 Binary files a/Editor/wx-editor.dll and b/Editor/wx-editor.dll differ diff --git a/Editor/wx-editor.xml.meta b/Editor/wx-editor.xml.meta index f8ad6267b..1bd6b0842 100644 --- a/Editor/wx-editor.xml.meta +++ b/Editor/wx-editor.xml.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: f847db20faa66610af5948c280c4a736 +guid: 296ab969be74914b1b1e071f7949c633 DefaultImporter: externalObjects: {} userData: diff --git a/Runtime/Plugins/wx-perf.dll b/Runtime/Plugins/wx-perf.dll index 5d0b9cded..05f537d4e 100644 Binary files a/Runtime/Plugins/wx-perf.dll and b/Runtime/Plugins/wx-perf.dll differ diff --git a/Runtime/Plugins/wx-runtime-editor.dll b/Runtime/Plugins/wx-runtime-editor.dll index 99b1791cc..fe3fcc43c 100644 Binary files a/Runtime/Plugins/wx-runtime-editor.dll and b/Runtime/Plugins/wx-runtime-editor.dll differ diff --git a/Runtime/Plugins/wx-runtime-editor.xml b/Runtime/Plugins/wx-runtime-editor.xml index 64b02fa45..bfe27b6ee 100644 --- a/Runtime/Plugins/wx-runtime-editor.xml +++ b/Runtime/Plugins/wx-runtime-editor.xml @@ -4,6 +4,91 @@ wx-runtime-editor + + + WX数据保护插件使用示例 + 演示如何使用数据保护功能来保护游戏中的重要数值 + + + + + 示例1:基础用法 - 存储和读取数据 + + + + + 示例2:安全获取数据(推荐方式) + + + + + 示例3:存储复杂对象 + + + + + 示例4:数据管理 + + + + + 数据篡改事件处理 + + + + + 处理数据篡改 + + + + + 示例:玩家属性数据结构 + 注意:使用 JsonUtility 序列化时,必须使用公共字段 + + + + + 游戏货币管理器示例 + 封装常用的货币操作,简化调用 + + + + + 初始化货币数据 + + + + + 获取金币数量 + + + + + 增加金币 + + + + + 消费金币 + + 是否消费成功 + + + + 获取钻石数量 + + + + + 增加钻石 + + + + + 消费钻石 + + 是否消费成功 + Banner 广告,详见 https://developers.weixin.qq.com/minigame/dev/guide/open-ability/ad/banner-ad.html @@ -3119,6 +3204,36 @@  是否结束 + + + 事件ID,开发者自行维护(必需) + + + + + 事件耗时,单位ms(可选)不填时为0 + + + + + 事件结果,默认成功(可选)不填时默认成功 + + + + + reportGameEvent的事件类型 + + + + + 成功事件 + + + + + 失败事件 + + 错误码,文档可见 https://developers.weixin.qq.com/minigame/dev/api/open-api/openlink/wx.createPageManager.html @@ -3295,7 +3410,7 @@ 需要基础库: `2.10.0` 小程序版本 可选值: - - 'develop': 开发版; + - 'develop': 开发版,提交代码审核时默认使用开发版进行审核。; - 'trial': 体验版; - 'release': 正式版; @@ -3473,6 +3588,14 @@ 客户端平台 + 可选值: + - 'ios': iOS微信(包含 iPhone、iPad); + - 'android': Android微信; + - 'ohos': HarmonyOS 手机端微信; + - 'ohos_pc': HarmonyOS PC微信; + - 'windows': Windows微信; + - 'mac': macOS微信; + - 'devtools': 微信开发者工具; @@ -3480,6 +3603,16 @@ 操作系统及版本 + + + 当前是否处于直接广告中 + + + + + 当前是否处于蒙层阶段 + + 需要基础库: `2.20.0` @@ -3546,6 +3679,11 @@ 直播间 id + + + 宿主传递的数据,第三方 app 中运行小游戏时返回 + + 启动小游戏的 query 参数 @@ -3576,6 +3714,11 @@ shareTicket,详见[获取更多转发信息](#) + + + 宿主app对应的场景值 + + 下边界坐标,单位:px @@ -3772,7 +3915,8 @@ 可选值: - 'ios': iOS微信(包含 iPhone、iPad); - 'android': Android微信; - - 'ohos': HarmonyOS微信; + - 'ohos': HarmonyOS 手机端微信; + - 'ohos_pc': HarmonyOS PC微信; - 'windows': Windows微信; - 'mac': macOS微信; - 'devtools': 微信开发者工具; @@ -5595,22 +5739,22 @@ 预告状态:0可用 1取消 2已用 - + 敏感数据对应的云 ID,开通[云开发](https://developers.weixin.qq.com/minigame/dev/wxcloud/basis/getting-started.html)的小程序才会返回,可通过云调用直接获取开放数据,详细见[云调用直接获取开放数据](https://developers.weixin.qq.com/minigame/dev/guide/open-ability/signature.html#method-cloud) - + 包括敏感数据在内的完整转发信息的加密数据,详细见[加密数据解密算法](https://developers.weixin.qq.com/minigame/dev/guide/open-ability/signature.html) - + 错误信息 - + 加密算法的初始向量,详细见[加密数据解密算法](https://developers.weixin.qq.com/minigame/dev/guide/open-ability/signature.html) @@ -5705,6 +5849,21 @@ 实验参数数组,不填则获取所有实验参数 + + + 实验ID,标识实验 + + + + + 参数名称 + + + + + 参数值 + + 需要基础库: `3.7.8` @@ -5826,6 +5985,67 @@ 本机局域网子网掩码,基础库 2.24.0 开始支持 + + + 需要基础库: `1.6.0` + 传入 true 会返回高度信息,由于获取高度需要较高精确度,会减慢接口返回速度 + + + + + 需要基础库: `2.9.0` + 高精度定位超时时间(ms),指定时间内返回最高精度,该值3000ms以上高精度定位才有效果 + + + + + 需要基础库: `2.9.0` + 开启高精度定位 + + + + + wgs84 返回 gps 坐标,gcj02 返回可用于 wx.openLocation 的坐标 + + + + + 位置的精确度,反应与真实位置之间的接近程度,可以理解成10即与真实位置相差10m,越小越精确 + + + + + 需要基础库: `1.2.0` + 高度,单位 m + + + + + 需要基础库: `1.2.0` + 水平精度,单位 m + + + + + 纬度,范围为 -90~90,负数表示南纬 + + + + + 经度,范围为 -180~180,负数表示西经 + + + + + 速度,单位 m/s + + + + + 需要基础库: `1.2.0` + 垂直精度,单位 m(Android 无法获取,返回 0) + + 需要基础库: `2.22.1` @@ -5941,6 +6161,17 @@ - itemSettings 只返回用户勾选过订阅面板中的“总是保持以上选择,不再询问”的订阅消息。 + + + shareTicket,详见[获取更多转发信息](#) + + + + + 需要基础库: `1.9.90` + 超时时间,单位 ms + + 封面广告组件展示状态码 @@ -6510,6 +6741,21 @@ - 'landscapeReverse': 横屏反方向,以 HOME 键在屏幕左侧为反方向; + + + 当前直玩广告是否由于异常流程而结束(如 下拉/搜索 进入正在直玩广告流程中的游戏) + + + + + 当前是否处于直接广告中 + + + + + 当前是否处于蒙层阶段 + + 错误信息,包含堆栈 @@ -6905,7 +7151,7 @@ - 视频号 id + 视频号id(参考格式为:sphcqO59YEPCvoe;查看路径为:微信客户端->我tab->视频号->右上角.->视频号名字-视频号ID) @@ -7225,6 +7471,32 @@ 自定义维度,基础库 v2.14.0 开始支持可选 + + + 错误信息 + | 错误码 | 错误信息 | 说明 | + | - | - | - | + | 0 | 人脸识别成功 | | + | 2002004 | 人脸识别失败 | | + | 2002006 | 用户取消/超时/不同意,导致未完成人脸识别 | | + | 2002007 | 本用户7天内人脸识别已通过,通过日期为XX | | + | 2002008 | 本日已调起过人脸识别 | or本月调用次数已达上限 | + | 2002009 | 无权限发起人脸识别 | | + + + + + 错误码 + | 错误码 | 错误信息 | 说明 | + | - | - | - | + | 0 | 人脸识别成功 | | + | 2002004 | 人脸识别失败 | | + | 2002006 | 用户取消/超时/不同意,导致未完成人脸识别 | | + | 2002007 | 本用户7天内人脸识别已通过,通过日期为XX | | + | 2002008 | 本日已调起过人脸识别 | or本月调用次数已达上限 | + | 2002009 | 无权限发起人脸识别 | | + + 购买数量。mode=game 时必填。购买数量。详见 [buyQuantity 限制说明](#buyQuantity限制说明)。 @@ -7610,7 +7882,7 @@ - 自定义的登录态 + 自定义的登录态。上限 1024 字符。 diff --git a/Runtime/Plugins/wx-runtime-editor.xml.meta b/Runtime/Plugins/wx-runtime-editor.xml.meta index d26b0d0b9..11b61f888 100644 --- a/Runtime/Plugins/wx-runtime-editor.xml.meta +++ b/Runtime/Plugins/wx-runtime-editor.xml.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 86cfe097f9cce0b88db9414b86df4ed1 +guid: 2d2c6260315bec2c3b9bb0b156fa3105 DefaultImporter: externalObjects: {} userData: diff --git a/Runtime/Plugins/wx-runtime.dll b/Runtime/Plugins/wx-runtime.dll index 102563c71..bbf1466b1 100644 Binary files a/Runtime/Plugins/wx-runtime.dll and b/Runtime/Plugins/wx-runtime.dll differ diff --git a/Runtime/Plugins/wx-runtime.xml b/Runtime/Plugins/wx-runtime.xml index 1838a1584..d377ce4ce 100644 --- a/Runtime/Plugins/wx-runtime.xml +++ b/Runtime/Plugins/wx-runtime.xml @@ -4,12 +4,91 @@ wx-runtime - + - 覆盖unity的PlayerPrefs - 注意:调用均为同步调用, 容易阻塞游戏主线程造成卡顿,不建议频繁调用 + WX数据保护插件使用示例 + 演示如何使用数据保护功能来保护游戏中的重要数值 + + + 示例1:基础用法 - 存储和读取数据 + + + + + 示例2:安全获取数据(推荐方式) + + + + + 示例3:存储复杂对象 + + + + + 示例4:数据管理 + + + + + 数据篡改事件处理 + + + + + 处理数据篡改 + + + + + 示例:玩家属性数据结构 + 注意:使用 JsonUtility 序列化时,必须使用公共字段 + + + + + 游戏货币管理器示例 + 封装常用的货币操作,简化调用 + + + + + 初始化货币数据 + + + + + 获取金币数量 + + + + + 增加金币 + + + + + 消费金币 + + 是否消费成功 + + + + 获取钻石数量 + + + + + 增加钻石 + + + + + 消费钻石 + + 是否消费成功 + Banner 广告,详见 https://developers.weixin.qq.com/minigame/dev/guide/open-ability/ad/banner-ad.html @@ -3125,6 +3204,36 @@  是否结束 + + + 事件ID,开发者自行维护(必需) + + + + + 事件耗时,单位ms(可选)不填时为0 + + + + + 事件结果,默认成功(可选)不填时默认成功 + + + + + reportGameEvent的事件类型 + + + + + 成功事件 + + + + + 失败事件 + + 错误码,文档可见 https://developers.weixin.qq.com/minigame/dev/api/open-api/openlink/wx.createPageManager.html @@ -3301,7 +3410,7 @@ 需要基础库: `2.10.0` 小程序版本 可选值: - - 'develop': 开发版; + - 'develop': 开发版,提交代码审核时默认使用开发版进行审核。; - 'trial': 体验版; - 'release': 正式版; @@ -3479,6 +3588,14 @@ 客户端平台 + 可选值: + - 'ios': iOS微信(包含 iPhone、iPad); + - 'android': Android微信; + - 'ohos': HarmonyOS 手机端微信; + - 'ohos_pc': HarmonyOS PC微信; + - 'windows': Windows微信; + - 'mac': macOS微信; + - 'devtools': 微信开发者工具; @@ -3486,6 +3603,16 @@ 操作系统及版本 + + + 当前是否处于直接广告中 + + + + + 当前是否处于蒙层阶段 + + 需要基础库: `2.20.0` @@ -3552,6 +3679,11 @@ 直播间 id + + + 宿主传递的数据,第三方 app 中运行小游戏时返回 + + 启动小游戏的 query 参数 @@ -3582,6 +3714,11 @@ shareTicket,详见[获取更多转发信息](#) + + + 宿主app对应的场景值 + + 下边界坐标,单位:px @@ -3778,7 +3915,8 @@ 可选值: - 'ios': iOS微信(包含 iPhone、iPad); - 'android': Android微信; - - 'ohos': HarmonyOS微信; + - 'ohos': HarmonyOS 手机端微信; + - 'ohos_pc': HarmonyOS PC微信; - 'windows': Windows微信; - 'mac': macOS微信; - 'devtools': 微信开发者工具; @@ -5601,22 +5739,22 @@ 预告状态:0可用 1取消 2已用 - + 敏感数据对应的云 ID,开通[云开发](https://developers.weixin.qq.com/minigame/dev/wxcloud/basis/getting-started.html)的小程序才会返回,可通过云调用直接获取开放数据,详细见[云调用直接获取开放数据](https://developers.weixin.qq.com/minigame/dev/guide/open-ability/signature.html#method-cloud) - + 包括敏感数据在内的完整转发信息的加密数据,详细见[加密数据解密算法](https://developers.weixin.qq.com/minigame/dev/guide/open-ability/signature.html) - + 错误信息 - + 加密算法的初始向量,详细见[加密数据解密算法](https://developers.weixin.qq.com/minigame/dev/guide/open-ability/signature.html) @@ -5711,6 +5849,21 @@ 实验参数数组,不填则获取所有实验参数 + + + 实验ID,标识实验 + + + + + 参数名称 + + + + + 参数值 + + 需要基础库: `3.7.8` @@ -5832,6 +5985,67 @@ 本机局域网子网掩码,基础库 2.24.0 开始支持 + + + 需要基础库: `1.6.0` + 传入 true 会返回高度信息,由于获取高度需要较高精确度,会减慢接口返回速度 + + + + + 需要基础库: `2.9.0` + 高精度定位超时时间(ms),指定时间内返回最高精度,该值3000ms以上高精度定位才有效果 + + + + + 需要基础库: `2.9.0` + 开启高精度定位 + + + + + wgs84 返回 gps 坐标,gcj02 返回可用于 wx.openLocation 的坐标 + + + + + 位置的精确度,反应与真实位置之间的接近程度,可以理解成10即与真实位置相差10m,越小越精确 + + + + + 需要基础库: `1.2.0` + 高度,单位 m + + + + + 需要基础库: `1.2.0` + 水平精度,单位 m + + + + + 纬度,范围为 -90~90,负数表示南纬 + + + + + 经度,范围为 -180~180,负数表示西经 + + + + + 速度,单位 m/s + + + + + 需要基础库: `1.2.0` + 垂直精度,单位 m(Android 无法获取,返回 0) + + 需要基础库: `2.22.1` @@ -5947,6 +6161,17 @@ - itemSettings 只返回用户勾选过订阅面板中的“总是保持以上选择,不再询问”的订阅消息。 + + + shareTicket,详见[获取更多转发信息](#) + + + + + 需要基础库: `1.9.90` + 超时时间,单位 ms + + 封面广告组件展示状态码 @@ -6516,6 +6741,21 @@ - 'landscapeReverse': 横屏反方向,以 HOME 键在屏幕左侧为反方向; + + + 当前直玩广告是否由于异常流程而结束(如 下拉/搜索 进入正在直玩广告流程中的游戏) + + + + + 当前是否处于直接广告中 + + + + + 当前是否处于蒙层阶段 + + 错误信息,包含堆栈 @@ -6911,7 +7151,7 @@ - 视频号 id + 视频号id(参考格式为:sphcqO59YEPCvoe;查看路径为:微信客户端->我tab->视频号->右上角.->视频号名字-视频号ID) @@ -7231,6 +7471,32 @@ 自定义维度,基础库 v2.14.0 开始支持可选 + + + 错误信息 + | 错误码 | 错误信息 | 说明 | + | - | - | - | + | 0 | 人脸识别成功 | | + | 2002004 | 人脸识别失败 | | + | 2002006 | 用户取消/超时/不同意,导致未完成人脸识别 | | + | 2002007 | 本用户7天内人脸识别已通过,通过日期为XX | | + | 2002008 | 本日已调起过人脸识别 | or本月调用次数已达上限 | + | 2002009 | 无权限发起人脸识别 | | + + + + + 错误码 + | 错误码 | 错误信息 | 说明 | + | - | - | - | + | 0 | 人脸识别成功 | | + | 2002004 | 人脸识别失败 | | + | 2002006 | 用户取消/超时/不同意,导致未完成人脸识别 | | + | 2002007 | 本用户7天内人脸识别已通过,通过日期为XX | | + | 2002008 | 本日已调起过人脸识别 | or本月调用次数已达上限 | + | 2002009 | 无权限发起人脸识别 | | + + 购买数量。mode=game 时必填。购买数量。详见 [buyQuantity 限制说明](#buyQuantity限制说明)。 @@ -7616,7 +7882,7 @@ - 自定义的登录态 + 自定义的登录态。上限 1024 字符。 @@ -9125,5 +9391,11 @@ 注册监听录制事件的回调函数。当对应事件触发时,回调函数会被执行 + + + 覆盖unity的PlayerPrefs + 注意:调用均为同步调用, 容易阻塞游戏主线程造成卡顿,不建议频繁调用 + + diff --git a/Runtime/Plugins/wx-runtime.xml.meta b/Runtime/Plugins/wx-runtime.xml.meta index abf9e048d..0aa5078e7 100644 --- a/Runtime/Plugins/wx-runtime.xml.meta +++ b/Runtime/Plugins/wx-runtime.xml.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 9a7c16358edeccc9e6507105d15b2cd3 +guid: 4c772f389151e36ccebc1c7d47ada8e7 DefaultImporter: externalObjects: {} userData: diff --git a/Runtime/WX.cs b/Runtime/WX.cs index 0049afc2d..50a3b46a1 100644 --- a/Runtime/WX.cs +++ b/Runtime/WX.cs @@ -279,7 +279,7 @@ namespace WeChatWASM /// /// [wx.exitChatTool(Object object)](https://developers.weixin.qq.com/minigame/dev/api/chattool/wx.exitChatTool.html) /// 需要基础库: `3.7.12` - /// 退出聊天工具模式 + /// 退出聊天工具开放能力模式 /// public static void ExitChatTool(ExitChatToolOption callback) { @@ -675,6 +675,7 @@ namespace WeChatWASM /// | 8 | 当天(自然日)赞官方贴子数 | 无需传入 | | /// | 9 | 当天(自然日)评论官方贴子数 | 无需传入 | | /// | 10 | 当天(自然日)发表到本圈子话题的贴子数 | 传入话题id,从mp-游戏圈话题管理处获取 | | + /// | 11 | 用户最近一次推荐游戏时间 | 无需传入 | 秒级时间戳 | | /// **encryptedData 解密后得到的 GameClubData 的结构** /// | 属性 | 类型 | 说明 | /// | ------- | ------- | -------------------------------------- | @@ -691,9 +692,22 @@ namespace WeChatWASM } /// - /// [wx.getGameExptInfo(Object object)](https://developers.weixin.qq.com/minigame/dev/api/data-analysis/wx.getGameExptInfo.html) + /// [wx.getGameExptInfo(Object options)](https://developers.weixin.qq.com/minigame/dev/api/data-analysis/wx.getGameExptInfo.html) /// 需要基础库: `3.8.8` /// 给定实验参数数组,获取对应的实验参数值 + /// **示例代码** + /// ```js + /// wx.getGameExptInfo({ + /// keyList: ['experiment_key1', 'experiment_key2'], + /// success(res) { + /// res.list.forEach((expParam) => { + /// console.log('实验ID:', expParam.expt_id); + /// console.log('参数名:', expParam.param_name); + /// console.log('参数值:', expParam.param_value); + /// }) + /// } + /// }); + /// ``` /// public static void GetGameExptInfo(GetGameExptInfoOption callback) { @@ -790,6 +804,14 @@ namespace WeChatWASM WXSDKManagerHandler.Instance.GetLocalIPAddress(callback); } + /// + /// [wx.getLocation(Object object)](https://developers.weixin.qq.com/minigame/dev/api/location/wx.getLocation.html) + /// + public static void GetLocation(GetLocationOption callback) + { + WXSDKManagerHandler.Instance.GetLocation(callback); + } + /// /// [wx.getNetworkType(Object object)](https://developers.weixin.qq.com/minigame/dev/api/device/network/wx.getNetworkType.html) /// 获取网络类型 @@ -916,6 +938,15 @@ namespace WeChatWASM WXSDKManagerHandler.Instance.GetSetting(callback); } + /// + /// [wx.getShareInfo(Object object)](https://developers.weixin.qq.com/minigame/dev/api/share/wx.getShareInfo.html) + /// 需要基础库: `1.1.0` + /// + public static void GetShareInfo(GetShareInfoOption callback) + { + WXSDKManagerHandler.Instance.GetShareInfo(callback); + } + /// /// [wx.getShowSplashAdStatus(Object object)](https://developers.weixin.qq.com/minigame/dev/api/ad/wx.getShowSplashAdStatus.html) /// 需要基础库: `3.7.8` @@ -1262,9 +1293,6 @@ namespace WeChatWASM /// 从 2.3.0 版本开始,若用户未点击小程序页面任意位置,则开发者将无法调用此接口自动跳转至其他小程序。 /// ##### 需要用户确认跳转 /// 从 2.3.0 版本开始,在跳转至其他小程序前,将统一增加弹窗,询问是否跳转,用户确认后才可以跳转其他小程序。如果用户点击取消,则回调 `fail cancel`。 - /// ##### 无需声明跳转名单,不限跳转数量(众测中) - /// 1. 从2020年4月24日起,使用跳转其他小程序功能将无需在全局配置中声明跳转名单,调用此接口时将不再校验所跳转的 AppID 是否在 navigateToMiniProgramAppIdList 中。 - /// 2. 从2020年4月24日起,跳转其他小程序将不再受数量限制,使用此功能时请注意遵守运营规范。 /// **运营规范** /// 平台将坚决打击小程序盒子等互推行为,使用此功能时请严格遵守[《微信小程序平台运营规范》](https://developers.weixin.qq.com/miniprogram/product/#_5-10-%E4%BA%92%E6%8E%A8%E8%A1%8C%E4%B8%BA),若发现小程序违反运营规范将被下架处理。 /// **关于调试** @@ -1700,6 +1728,45 @@ namespace WeChatWASM WXSDKManagerHandler.Instance.ReportScene(callback); } + /// + /// [wx.requestFacialRecognition(Object object)](https://developers.weixin.qq.com/minigame/dev/api/open-api/account-info/wx.requestFacialRecognition.html) + /// 需要基础库: `3.11.2` + /// 发起人脸识别验证,用于对可疑用户进行身份验证和防沉迷检查。该接口会调起微信的人脸识别系统,验证用户身份以确保游戏安全和合规性。 + /// **处理流程** + /// 1. 开发者调用 `wx.requestFacialRecognition` 发起人脸识别。 + /// 2. 系统根据策略判定是否需要展示授权弹窗。 + /// - 若判定为"不展示弹窗":立即回调结果,示例:`{ errCode: 0, errMsg: '本用户7天内人脸识别已通过' }` + /// - 若判定为"需展示弹窗":进入步骤 3。 + /// 3. 系统展示授权弹窗。 + /// - 玩家拒绝:立即回调 `fail`,`errCode = 2002006` + /// - 玩家同意:进入步骤 4。 + /// 4. 系统开始进行人脸识别验证 + /// - 玩家在跳转页面中完成活体/人脸识别;关闭页面返回游戏。 + /// 5. 系统回调最终识别结果返回 + /// **示例代码** + /// ```js + /// wx.requestFacialRecognition({ + /// success(res) { + /// // 人脸识别通过或 7 天内已通过 + /// // 形如:{ errCode: 0, errMsg: 'ok' } + /// console.log('requestFacialRecognition success:', res) + /// }, + /// fail(err) { + /// // 失败或受限等场景 + /// console.log('requestFacialRecognition fail:', err) + /// }, + /// complete(res) { + /// // 无论成功失败均会触发 + /// console.log('requestFacialRecognition complete:', res) + /// } + /// }) + /// ``` + /// + public static void RequestFacialRecognition(RequestFacialRecognitionOption callback) + { + WXSDKManagerHandler.Instance.RequestFacialRecognition(callback); + } + /// /// [wx.requestMidasFriendPayment(Object object)](https://developers.weixin.qq.com/minigame/dev/api/midas-payment/wx.requestMidasFriendPayment.html) /// 需要基础库: `2.11.0` @@ -2043,6 +2110,8 @@ namespace WeChatWASM /// [wx.setDeviceOrientation(Object object)](https://developers.weixin.qq.com/minigame/dev/api/device/orientation/wx.setDeviceOrientation.html) /// 需要基础库: `2.26.0` /// 切换横竖屏。接口调用成功后会触发 wx.onDeviceOrientationChange 事件 + /// **注意** + /// - PC小程序处于全屏时,无法切换横竖屏。 /// public static void SetDeviceOrientation(SetDeviceOrientationOption callback) { @@ -2763,6 +2832,15 @@ namespace WeChatWASM WXSDKManagerHandler.Instance.ReportEvent(eventId, data); } + /// + /// [wx.reportMonitor(string name, number value)](https://developers.weixin.qq.com/minigame/dev/api/data-analysis/wx.reportMonitor.html) + /// 需要基础库: `2.1.2` + /// + public static void ReportMonitor(string name, double value) + { + WXSDKManagerHandler.Instance.ReportMonitor(name, value); + } + /// /// [wx.reportPerformance(Number id, Number value, String|Array dimensions)](https://developers.weixin.qq.com/minigame/dev/api/base/performance/wx.reportPerformance.html) /// 需要基础库: `2.10.0` @@ -3121,6 +3199,34 @@ namespace WeChatWASM WXSDKManagerHandler.Instance.OffDeviceOrientationChange(result); } + /// + /// [wx.onDirectAdStatusChange(function listener)](https://developers.weixin.qq.com/minigame/dev/api/ad/wx.onDirectAdStatusChange.html) + /// 需要基础库: `3.11.2` + /// 监听监听直玩广告状态变化 + /// **示例代码** + /// ```js + /// wx.onDirectAdStatusChange(res => { + /// // 会有如下的几种状态值组合 + /// // a) { isInMask: true, isInDirectGameAd: true } -> 表示当前正在直玩广告 且 未戳破蒙层 + /// // b) { isInMask: false, isInDirectGameAd: true } -> 表示当前正在直玩广告 且 戳破了蒙层 + /// // c) { isInMask: false, isInDirectGameAd: false, isEndByAbnormal: false }, -> 表示倒计时结束了,并且选择了继续玩 + /// // d) { isInMask: false, isInDirectGameAd: false, isEndByAbnormal: true }, -> 表示由于异常流程而结束 + /// console.log(res.isInMask) + /// console.log(res.isInDirectGameAd) + /// console.log(res.isEndByAbnormal) + /// }) + /// ``` + /// + public static void OnDirectAdStatusChange(Action result) + { + WXSDKManagerHandler.Instance.OnDirectAdStatusChange(result); + } + + public static void OffDirectAdStatusChange(Action result) + { + WXSDKManagerHandler.Instance.OffDirectAdStatusChange(result); + } + /// /// [wx.onError(function listener)](https://developers.weixin.qq.com/minigame/dev/api/base/app/app-event/wx.onError.html) /// 监听全局错误事件 @@ -3495,21 +3601,21 @@ namespace WeChatWASM /// 需要基础库: `2.8.1` /// 监听用户主动截屏事件。用户使用系统截屏按键截屏时触发,只能注册一个监听 /// **示例代码** + /// 页面要先调用wx.showShareMenu()来允许调用 /// ```js /// wx.onUserCaptureScreen(function (res) { /// console.log('用户截屏了') /// return { /// query: "parameter=test", // 通过截屏图片打开小程序的query参数 /// promise: new Promise((resolve) => { // 通过promise延时传递小程序的query参数 - /// setTimeout(() => { - /// resolve({ - /// query: "parameter=test2", - /// }) - /// }, 1000) // 在1秒内对query进行解析 - /// }) + /// setTimeout(() => { + /// resolve({ + /// query: "parameter=test2", + /// }) + /// }, 1000) // 在1秒内对query进行解析 + /// }) /// } - /// } - /// ) + /// }) /// ``` /// public static void OnUserCaptureScreen(Action result) @@ -3643,7 +3749,7 @@ namespace WeChatWASM /// /// [wx.onCopyUrl(function listener)](https://developers.weixin.qq.com/minigame/dev/api/share/wx.onCopyUrl.html) /// 需要基础库: `2.14.3` - /// 监听用户点击右上角菜单的「复制链接」按钮时触发的事件。本接口为 Beta 版本,暂只在 Android 平台支持。 + /// 监听用户点击右上角菜单的「复制链接」按钮时触发的事件。 /// public static void OnCopyUrl(Action> callback) { @@ -3831,6 +3937,23 @@ namespace WeChatWASM return WXSDKManagerHandler.GetDeviceInfo(); } + /// + /// [Object wx.getDirectAdStatusSync()](https://developers.weixin.qq.com/minigame/dev/api/ad/wx.getDirectAdStatusSync.html) + /// 需要基础库: `3.11.2` + /// 获取直玩广告组件展示状态。 + /// **示例代码** + /// ```js + /// const statusInfo = wx.getDirectAdStatusSync(); + /// console.log(statusInfo.isInMask) // 当前是否在蒙层阶段 + /// console.log(statusInfo.isInDirectGameAd) // 当前是否在直玩广告中 + /// ``` + /// + /// + public static DirectAdStatusInfo GetDirectAdStatusSync() + { + return WXSDKManagerHandler.GetDirectAdStatusSync(); + } + /// /// [Object wx.getEnterOptionsSync()](https://developers.weixin.qq.com/minigame/dev/api/base/app/life-cycle/wx.getEnterOptionsSync.html) /// 需要基础库: `2.13.2` @@ -4045,19 +4168,19 @@ namespace WeChatWASM } /// - /// [[ImageData](https://developers.weixin.qq.com/minigame/dev/api/render/image/ImageData.html) wx.createImageData(number width, number height)](https://developers.weixin.qq.com/minigame/dev/api/render/image/wx.createImageData.html) + /// [[ImageData](https://developers.weixin.qq.com/minigame/dev/api/render/image/ImageData.html) wx.createImageData(number width, number height, Uint8ClampedArray data)](https://developers.weixin.qq.com/minigame/dev/api/render/image/wx.createImageData.html) /// 需要基础库: `3.4.10` - /// 这里有两种使用方法, 一种是指定ImageData的宽和高, 另外一种是使用ImageData, 通过它本身的宽高尺寸来构建新的对象。 + /// 这里有两种使用方法, 一种是指定ImageData的宽和高, 另外一种使用已有的ImageData的图像二进制数据,来构建新的对象。 /// **示例代码** /// ```js - /// const imageData1 = wx.createImageData(100, 100) - /// const imageData2 = wx.createImageData(imageData1) + /// const imageData1 = wx.createImageData(100, 100) + /// const imageData2 = wx.createImageData(imageData1.data, 100, 100) /// ``` /// /// - public static ImageData CreateImageData(double width, double height) + public static ImageData CreateImageData(double width, double height, int[] data) { - return WXSDKManagerHandler.CreateImageData(width, height); + return WXSDKManagerHandler.CreateImageData(width, height, data); } /// diff --git a/Runtime/WXBase.cs b/Runtime/WXBase.cs index fed9ae2b8..7f7718edd 100644 --- a/Runtime/WXBase.cs +++ b/Runtime/WXBase.cs @@ -1136,6 +1136,14 @@ namespace WeChatWASM { WXSDKManagerHandler.Instance.NotifyMiniProgramPlayableStatus(option); } + /// + /// 上报自定义打点数据 + /// + /// + public static void ReportGameEvent(ReportGameEventOption option) + { + WXSDKManagerHandler.Instance.ReportGameEvent(option); + } #endregion #region 虚拟支付 /// diff --git a/Runtime/WXTouchInputModule.cs b/Runtime/WXTouchInputModule.cs new file mode 100644 index 000000000..a685c29bc --- /dev/null +++ b/Runtime/WXTouchInputModule.cs @@ -0,0 +1,186 @@ +#if UNITY_WEBGL || WEIXINMINIGAME || UNITY_EDITOR +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Events; +using UnityEngine.EventSystems; +using UnityEngine.UI; + +/** + * WxTouch输入模块,结合 WXTouchInputOverride 使用 + * 用于拦截所有Button事件调用,确保事件只被触发一次,避免重复触发问题 + * 除会拦截带 Button 组件的 ExecuteEvents.pointerClickHandler 事件外,逻辑与 StandaloneInputModule 均一致 + * 需要在场景中添加 WXTouchInputOverride 组件使用,且保证不要有其他的 StandaloneInputModule + */ +public class WXTouchInputModule : StandaloneInputModule +{ + private const float doubleClickTime = 0.3f; + + public override void Process() + { + if (!eventSystem.isFocused && ShouldIgnoreEventsOnNoFocus()) + return; + bool usedEvent = SendUpdateEventToSelectedObject(); + if (!ProcessTouchEvents() && input.mousePresent) + ProcessMouseEvent(); + if (eventSystem.sendNavigationEvents) + { + if (!usedEvent) + usedEvent |= SendMoveEventToSelectedObject(); + + if (!usedEvent) + SendSubmitEventToSelectedObject(); + } + } + + private bool ShouldIgnoreEventsOnNoFocus() + { +#if UNITY_EDITOR + return !UnityEditor.EditorApplication.isRemoteConnected; +#else + return true; +#endif + } + + private bool ProcessTouchEvents() + { + for (int i = 0; i < input.touchCount; ++i) + { + Touch touch = input.GetTouch(i); + if (touch.type == TouchType.Indirect) + continue; + + bool released; + bool pressed; + var pointer = GetTouchPointerEventData(touch, out pressed, out released); + + ProcessTouchPress(pointer, pressed, released); + + if (!released) + { + ProcessMove(pointer); + ProcessDrag(pointer); + } + else + RemovePointerData(pointer); + } + return input.touchCount > 0; + } + + // released 后会拦截 Button 的 ExecuteEvents.pointerClickHandler ,其余逻辑与 StandaloneInputModule 保持一致 + protected new void ProcessTouchPress(PointerEventData pointerEvent, bool pressed, bool released) + { + var currentOverGo = pointerEvent.pointerCurrentRaycast.gameObject; + + // PointerDown notification + if (pressed) + { + pointerEvent.eligibleForClick = true; + pointerEvent.delta = Vector2.zero; + pointerEvent.dragging = false; + pointerEvent.useDragThreshold = true; + pointerEvent.pressPosition = pointerEvent.position; + pointerEvent.pointerPressRaycast = pointerEvent.pointerCurrentRaycast; + + DeselectIfSelectionChanged(currentOverGo, pointerEvent); + + if (pointerEvent.pointerEnter != currentOverGo) + { + // send a pointer enter to the touched element if it isn't the one to select... + HandlePointerExitAndEnter(pointerEvent, currentOverGo); + pointerEvent.pointerEnter = currentOverGo; + } + + var resetDiffTime = Time.unscaledTime - pointerEvent.clickTime; + if (resetDiffTime >= doubleClickTime) + { + pointerEvent.clickCount = 0; + } + + // search for the control that will receive the press + // if we can't find a press handler set the press + // handler to be what would receive a click. + var newPressed = ExecuteEvents.ExecuteHierarchy(currentOverGo, pointerEvent, ExecuteEvents.pointerDownHandler); + + var newClick = ExecuteEvents.GetEventHandler(currentOverGo); + + // didnt find a press handler... search for a click handler + if (newPressed == null) + newPressed = newClick; + + // Debug.Log("Pressed: " + newPressed); + + float time = Time.unscaledTime; + + if (newPressed == pointerEvent.lastPress) + { + var diffTime = time - pointerEvent.clickTime; + if (diffTime < doubleClickTime) + ++pointerEvent.clickCount; + else + pointerEvent.clickCount = 1; + + pointerEvent.clickTime = time; + } + else + { + pointerEvent.clickCount = 1; + } + + pointerEvent.pointerPress = newPressed; + pointerEvent.rawPointerPress = currentOverGo; + pointerEvent.pointerClick = newClick; + + pointerEvent.clickTime = time; + + // Save the drag handler as well + pointerEvent.pointerDrag = ExecuteEvents.GetEventHandler(currentOverGo); + + if (pointerEvent.pointerDrag != null) + ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.initializePotentialDrag); + } + + // PointerUp notification + if (released) + { + // Debug.Log("Executing pressup on: " + pointer.pointerPress); + ExecuteEvents.Execute(pointerEvent.pointerPress, pointerEvent, ExecuteEvents.pointerUpHandler); + // Debug.Log("KeyCode: " + pointer.eventData.keyCode); + + // see if we mouse up on the same element that we clicked on... + var pointerClickHandler = ExecuteEvents.GetEventHandler(currentOverGo); + + // PointerClick and Drop events + if (pointerEvent.pointerClick == pointerClickHandler && pointerEvent.eligibleForClick) + { + bool shouldHandleInWx = currentOverGo != null && currentOverGo.GetComponentInParent() != null; + if (!shouldHandleInWx) + { + ExecuteEvents.Execute(pointerEvent.pointerClick, pointerEvent, ExecuteEvents.pointerClickHandler); + } + } + + if (pointerEvent.pointerDrag != null && pointerEvent.dragging) + { + ExecuteEvents.ExecuteHierarchy(currentOverGo, pointerEvent, ExecuteEvents.dropHandler); + } + + pointerEvent.eligibleForClick = false; + pointerEvent.pointerPress = null; + pointerEvent.rawPointerPress = null; + pointerEvent.pointerClick = null; + + if (pointerEvent.pointerDrag != null && pointerEvent.dragging) + ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.endDragHandler); + + pointerEvent.dragging = false; + pointerEvent.pointerDrag = null; + + // send exit events as we need to simulate this on touch up on touch device + ExecuteEvents.ExecuteHierarchy(pointerEvent.pointerEnter, pointerEvent, ExecuteEvents.pointerExitHandler); + pointerEvent.pointerEnter = null; + } + + //m_InputPointerEvent = pointerEvent; + } +} +#endif \ No newline at end of file diff --git a/Runtime/WXTouchInputModule.cs.meta b/Runtime/WXTouchInputModule.cs.meta new file mode 100644 index 000000000..ffc1c36c7 --- /dev/null +++ b/Runtime/WXTouchInputModule.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6226ce8c6cf3dd24d95cfa430c9755d3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/WXTouchInputOverride.cs b/Runtime/WXTouchInputOverride.cs index 82a963b51..831f7a540 100644 --- a/Runtime/WXTouchInputOverride.cs +++ b/Runtime/WXTouchInputOverride.cs @@ -21,17 +21,17 @@ internal class TouchData * 所以需要使用WX的触控接口重新覆盖Unity的BaseInput关于触控方面的接口 * 通过设置StandaloneInputModule.inputOverride的方式来实现 */ -[RequireComponent(typeof(StandaloneInputModule))] +[RequireComponent(typeof(WXTouchInputModule))] public class WXTouchInputOverride : BaseInput { private bool _isInitWechatSDK; private readonly List _touches = new List(); - private StandaloneInputModule _standaloneInputModule = null; + private WXTouchInputModule _standaloneInputModule = null; protected override void Awake() { base.Awake(); - _standaloneInputModule = GetComponent(); + _standaloneInputModule = GetComponent(); } protected override void OnEnable() @@ -138,11 +138,16 @@ public class WXTouchInputOverride : BaseInput Button button = selectedObject.GetComponent