- 游戏开发
- 移动开发
- WebAssembly
【免费下载链接】minigame-unity-webgl-transform
微信小游戏Unity引擎适配器文档。
导读
在微信小游戏中,使用wx.createVideo创建的视频默认层级最高,会直接盖住整个游戏画面。但很多游戏场景需要在视频之上叠加交互元素,例如"跳过播放"按钮、进度提示、玩法引导等。本指南基于minigame-unity-webgl-transform仓库中的 Demo/WX_Video 视频 Demo,完整讲解如何通过underGameView=true将视频渲染到游戏画布之下,让"画布有内容的地方显示游戏画面,没内容的地方透出视频",同时配套 Unity 侧的相机清屏与透明画布配置,帮助开发者在 Unity WebGL 转换到微信小游戏的工程中实现"视频打底 + 游戏交互层叠"的效果。
读完本文,你将掌握:underGameView的底层实现原理、Unity 主相机与TransparentBackground.jslib的配套配置、小游戏运行时video.js的关键改动点,以及完整的 C# 调用示例与常见坑位排查。
一、实现原理:为什么视频默认会盖住游戏画面
微信小游戏的视频组件(wx.createVideo)本质上是原生渲染层组件,它运行在小游戏 WebView/Canvas 渲染栈的最上层,优先级高于 Unity 通过 WebGL 渲染出来的游戏画面。因此默认情况下,无论游戏画面绘制了什么,视频都会完整覆盖其上。
要让"跳过按钮"等游戏 UI 显示在视频之上,核心思路是改变视频与画布的层级关系:
- 创建视频时传入参数
underGameView=true,让视频在小游戏画布(即游戏画面)之下播放; - 由于视频此时位于画布下方,游戏画布必须是部分透明的——画布上有内容(不透明像素)的地方显示游戏画面,画布上透明(没有绘制内容)的区域则透出底层的视频画面。
这就形成了"视频打底、游戏画面按需覆盖"的合成效果,交互按钮因为绘制在游戏画布上,天然位于视频之上。
从仓库中的 PlayVideo.cs 可以看到,创建视频时只需显式声明underGameView = true,并配合controls = false、autoplay = true等参数即可:
var video = WX.CreateVideo( new WXCreateVideoParam() { src = "http://wxsnsdy.tc.qq.com/...", // 视频地址(CDN 或本地路径) controls = false, // 隐藏系统控制条 showProgress = false, // 不显示进度条 showProgressInControlMode = false, autoplay = true, // 自动播放 showCenterPlayBtn = false, // 隐藏居中播放按钮 underGameView = true, // 关键参数:视频置于游戏画面之下 width = ((int)systemInfo.screenWidth), // 铺满全屏 height = ((int)systemInfo.screenHeight), } );二、Unity 侧配置:相机清屏与透明画布
仅仅把视频放到画布之下还不够,游戏画面本身必须是"可透明"的,否则一张不透明的黑色/彩色画面仍然会把视频完全挡住。因此需要在 Unity 工程中完成两处配置。
2.1 主相机:Clear Flags 改为 Solid Color,颜色设为黑色
将场景主相机的Clear Flags从Skybox/Solid Color默认值改为Solid Color,并把背景颜色设置为黑色。
这一步的目的是让相机清理屏幕时生成的是"全透明"的画布底,而不是天空盒或其它不透明背景。透明区域会透出下层视频,Unity 中正常渲染的 UI、模型、粒子等内容则按正常层级绘制在视频之上。仓库 Demo 的 SampleScene.unity 即按此规则配置。
2.2 引入 TransparentBackground.jslib
将 Demo 工程下的 Assets/Plugins/TransparentBackground.jslib 复制到你的 Unity 工程(放置于Assets/Plugins下)。它的作用是拦截 WebGL 的glClear调用,跳过"只清除 Alpha 通道"的清屏操作:
var LibraryGLClear = { glClear: function(mask) { if (mask == 0x00004000) { var v = GLctx.getParameter(GLctx.COLOR_WRITEMASK); if (GameGlobal.enableTransparentCanvas && !v[0] && !v[1] && !v[2] && v[3]) // We are trying to clear alpha only -- skip. return; } GLctx.clear(mask); } }; mergeInto(LibraryManager.library, LibraryGLClear);其逻辑可以这样理解:
0x00004000是 WebGL 中gl.COLOR_BUFFER_BIT的掩码值,只有清除颜色缓冲时才进入判断;- 通过
glGetParameter(GL_COLOR_WRITEMASK)读取当前颜色写入掩码,当恰好处于"只写 Alpha、不写 RGB"的状态(!v[0] && !v[1] && !v[2] && v[3])时,说明引擎正在执行"把 Alpha 清零"这类操作; - 配合全局开关
GameGlobal.enableTransparentCanvas,仅在视频需要置底(透明画布开启)时跳过这次清屏,从而保留画布的透明区域,让视频透出。
需要注意:该 jslib 在仓库中位于Assets/Plugins目录(TransparentBackground.jslib,同目录文件 API_V2 版本 内容一致)。Unity 导出 WebGL 时会自动将Plugins目录下的.jslib编译进最终的unity.js,无需额外注册。原文档特别强调"修改了下清理规则,否则可能导致正常情况下游戏画面异常",即不能无脑跳过所有清屏调用,必须严格限制在"透明画布开启且仅清 Alpha"的条件下,否则会影响非视频场景下的正常渲染。
三、小游戏侧配置:修改 video.js 联动透明画布开关
GameGlobal.enableTransparentCanvas这个全局开关需要在小游戏运行时中根据视频的创建/销毁时机自动打开和关闭。新版导出插件会自动完成该改动,若你的工程使用的是旧版插件,需要手动修改小游戏包内的minigame/unity-sdk/video.js,改动点如下:
WXCreateVideo(conf) { const id = new Date().getTime() .toString(32) + Math.random().toString(32); // 增加这之间部分代码(开始) const params = JSON.parse(conf); if (params.underGameView) { GameGlobal.enableTransparentCanvas = true; } videos[id] = wx.createVideo(params); // 增加这之间代码(结束) return id; }, WXVideoAddListener(id, key) { if (videos[id]) { videos[id]key => { moduleHelper.send('OnVideoCallback', JSON.stringify({ callbackId: id, errMsg: key, position: e && e.position, buffered: e && e.buffered, duration: e && e.duration, })); if (key === 'onError') { GameGlobal.enableTransparentCanvas = false; // 增加这行 console.error(e); } }); } else { console.error(msg, id); } }, WXVideoDestroy(id) { if (videos[id]) { videos[id].destroy(); } else { console.error(msg, id); } GameGlobal.enableTransparentCanvas = false; // 增加这行 },三处改动的职责分别对应三个生命周期节点:
- 创建视频时(
WXCreateVideo):解析conf参数,若包含underGameView则开启GameGlobal.enableTransparentCanvas = true,激活透明画布(此时 jslib 中的清屏拦截逻辑才会生效); - 视频报错时(
WXVideoAddListener中key === 'onError'):关闭透明画布开关,避免视频加载失败后游戏画面持续处于透明状态而显示异常; - 销毁视频时(
WXVideoDestroy):同样关闭开关,让画布恢复不透明,保证后续正常游戏画面不受影响。
从源码结构看,GameGlobal是微信小游戏运行时的全局对象,enableTransparentCanvas作为自定义扩展标志位,被 Unity 侧注入的TransparentBackground.jslib读取,从而在两套渲染逻辑(小游戏原生视频层与 Unity WebGL 画布)之间建立协同。
四、完整调用链:从 C# 到渲染层的落地
仓库 Demo 给出了一个完整的可运行示例。在 PlayVideo.cs 中,视频创建被放在WX.InitSDK的回调里,保证微信小游戏 SDK 初始化完成后再调用视频 API:
public class PlayVideo : MonoBehaviour { void Start() { var btn = this.GetComponent<Button>(); btn.onClick.AddListener(OnClick); this.AutoPlayVideo(); } private void AutoPlayVideo() { WX.InitSDK((int code) => { var systemInfo = WX.GetSystemInfoSync(); var video = WX.CreateVideo(new WXCreateVideoParam() { src = "http://wxsnsdy.tc.qq.com/...", controls = false, showProgress = false, showProgressInControlMode = false, autoplay = true, showCenterPlayBtn = false, underGameView = true, width = (int)systemInfo.screenWidth, height = (int)systemInfo.screenHeight, }); video.OnPlay(() => Debug.Log("video on play")); video.OnError(() => Debug.Log("video on error")); }); } }关键要点:
WX.InitSDK是微信小游戏 Unity SDK 的入口,视频类 API 需在其回调中调用;WXCreateVideoParam中underGameView = true是本方案的核心开关,它会通过 SDK 序列化传入小游戏侧wx.createVideo;- 视频尺寸直接取
GetSystemInfoSync()的screenWidth/screenHeight铺满全屏,这样视频恰好作为底层背景; Button组件挂在同一 GameObject 上,验证了"视频之下 + 游戏 UI 之上"的交互层叠:点击按钮时OnClick正常响应,而视频位于画布之下不会遮挡按钮。
更多视频 API 的完整参数说明可参考仓库 API_V2 示例中的 Video.cs,其中underGameView(对应CreateVideoOption.underGameView)与x/y/width/height、controls、autoplay、loop、muted、poster、initialTime、playbackRate、live、objectFit、autoPauseIfNavigate、autoPauseIfOpenNative等 20 余个参数一同构成了wx.createVideo的完整配置面,且支持OnEnded/OnError/OnPause/OnPlay/OnProgress/OnTimeUpdate/OnWaiting等回调绑定。
五、常见问题与排查建议
结合仓库 Design/AudioAndVideo.md 中关于 WXVideo 的实践记录,使用underGameView置底方案时需特别注意以下几点:
- iOS 设置
underGameView后黑屏、有声音没画面:需要在微信开发者工具/客户端开启高性能模式,这是已知的平台渲染限制; - 开发者工具无法播放,真机正常:开发者工具暂时存在异常,可先主动切换到
3.4.10版本基础库验证; - 视频加载失败导致画面异常:
onError时必须关闭GameGlobal.enableTransparentCanvas,避免画布一直保持透明;销毁视频时同样需要关闭开关; - VideoPlayer 与 WXVideo 的选择:如果只是单纯的全屏视频播放,官方更推荐使用小游戏 API 视频播放能力(
wx.createVideo);Unity 的VideoPlayer组件也已自动适配微信小游戏,但其平台支持版本有门槛(iOS 高性能+ 需 8.0.55、iOS 高性能需 8.0.41、安卓需 8.0.40、PC/开发者工具需基础库 3.2.1); - 跨域与视频源:iOS 上视频无法播放时优先排查服务端跨域配置,微信小游戏运行环境要求服务端允许
Origin weapp://wechat-game-runtime的跨域访问,否则会报Access-Control-Allow-Origin错误。
六、小结
"视频置底 + 交互层叠"的本质是打通三个环节:小游戏侧通过underGameView=true把原生视频层放到画布之下,并用GameGlobal.enableTransparentCanvas控制透明画布的开关;Unity 侧通过主相机 Solid Color 清屏(黑色)让画布具备透明底,再借助TransparentBackground.jslib精确拦截"仅清 Alpha"的glClear调用以保留透明区域;C# 侧只需在WX.InitSDK回调中创建带underGameView参数的视频即可。掌握这条调用链,即可在微信小游戏中实现"视频背景 + 跳过按钮"等常见交互,参考实现见仓库 Demo/WX_Video 工程。
- 游戏开发
- 移动开发
- WebAssembly
【免费下载链接】minigame-unity-webgl-transform
微信小游戏Unity引擎适配器文档。
相关推荐
微信小游戏 Unity 音视频适配全指南:AudioAndVideo 实战详解
微信小游戏 Unity 音视频适配全指南:AudioAndVideo 实战详解 本指南围绕微信小游戏 Unity 引擎适配器的音视频适配方案展开,核心覆盖 Un
游戏开发移动开发WebAssemblyUnity游戏微信小游戏快速适配完整指南
微信小游戏Unity WebGL适配方案(简称Unity WebGL小游戏适配)是一套专门为Unity游戏开发者设计的完整解决方案。该方案基于WebAssemb
游戏开发移动开发WebAssemblyUnity游戏移植微信小游戏:快速适配完整指南
Unity游戏移植微信小游戏:快速适配完整指南 想要将现有的Unity游戏快速移植到微信小游戏平台吗?本指南为您提供一套完整的Unity游戏适配和微信小游戏转换
游戏开发移动开发WebAssembly
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考