
简介这是微信小游戏《果蔬去哪了》的完整工程源码与配套资源面向希望从零了解微信小游戏开发流程的开发者或独立游戏爱好者。源码基于微信小程序框架与JavaScript实现覆盖事件监听、动画播放、计分与关卡逻辑、资源预加载、数据存储及性能优化等关键模块参考价值高。压缩包共738个文件以json配置、png图片、js脚本为主另有atlas、plist、prefab等Cocos Creator描述文件及mp3、mp4音视频素材整体约6.79MB结构清晰。已有612人学习下载。通过这套项目可获得可运行的完整源码还能从图片、动画等资源的设计组织中掌握休闲游戏从界面搭建到交互实现的实战技巧使用时请勿二次分发尊重原创。 《果蔬去哪了》这类休闲游戏近两年在微信小游戏里确实跑出了不少爆款核心玩法简单、用户门槛低再加上微信自带的社交裂变属性很适合作为新手入局小游戏赛道的练手项目。正好手头在整理一套完整的上线源码趁这个机会把整个项目从设计、源码结构到Unity打包、排行榜接入的完整链路拆开揉碎讲一遍。1. 项目定位与游戏设计思路解析1.1 核心玩法与关卡节奏设计《果蔬去哪了》本质上是典型的识别匹配类休闲玩法屏幕中会生成一堆果蔬图标玩家需要在限定时间内按题目要求找出指定的果蔬或者将散落的果蔬拖入对应的分类筐中。听起来简单但这个品类能持续吸引玩家的关键其实在关卡节奏和反馈设计上。从关卡数值看第一关通常控制在15秒、8个果蔬、只找1种目标到第10关会变成40秒、20个果蔬、同时找3种目标并且加入干扰项——外观相似但分类不同的果蔬比如樱桃和圣女果逼迫玩家在紧张时间内做判断。这种低门槛进入、渐进式加压的设计是休闲小游戏留存数据好看的核心原因。我看到的这套源码里关卡配置是独立的Json文件里面有timeLimit、targetList、itemCount、scorePerHit等字段。这样做的好处是策划调数值不用动代码直接改配置表就行。后续如果你想做成运营活动比如周末双倍关卡只需要多写几份配置运行时按日期加载非常灵活。1.2 引擎选型为什么走Unity路线很多新手会纠结做微信小游戏到底用Laya、Cocos还是Unity。这套源码是基于Unity 2022国际版开发的选择这个方案有几个实际考量第一Unity的UI系统和动画系统非常成熟对于果蔬图标这类需要大量动效反馈的休闲游戏开发效率明显更高。第二微信小游戏本质上是一个WebGL渲染环境Unity打包小游戏是通过把IL2CPP编译成WebAssembly来运行的性能上限比其他引擎高。第三如果你后续想把手游直接转小游戏或者小游戏转回AppUnity方案是唯一能实现两开两用的路线。当然Unity方案也有代价包体控制难度大启动加载时间偏长。但这套源码里用了AssetBundle分包和远程资源加载Resources.Load改为Bundle.Load把首包压到了3MB以内这个体量在微信小游戏审核里是很有优势的。2. 源码结构拆解与核心逻辑实现2.1 目录结构与模块划分拿到源码后别急着跑先把目录结构摸清楚。这套项目的核心目录大致如下Assets/ ├── Plugins/ # unity-webgl、微信SDK桥接 ├── Resources/ # 本地配置、预置体 ├── Scripts/ │ ├── Game/ # 游戏核心逻辑 │ ├── UI/ # 界面控制层 │ ├── Data/ # Json解析、数据模型 │ ├── Audio/ # 音效管理 │ └── Platform/ # 平台适配微信、安卓、iOS ├── Art/ # 图集、材质、动画 └── StreamingAssets/ # AssetBundle清单重点说下Platform目录这是Unity小游戏项目区别于普通手游项目的关键。里面封装了WXSDKHandler类统一对外提供Login、Share、GetFriendsRank、ShowInterstitialAd等接口。后续所有需要调微信API的地方都是通过这个Handler间接调用而不是直接写WX现场方法。这样做的目的只有一个方便你在Unity编辑器里模拟调试排行榜和分享逻辑不用每次都上传到真机看效果。2.2 果蔬生成与对象池设计果蔬在场景里的生成与回收源码里用的是经典的对象池方案。每个果蔬是一个Prefab池子初始容量是30个超过上限的果蔬不会立即销毁而是SetActive(false)后挂到空闲链表里等待下次复用。我特别留意了它的随机算法生成果蔬时会根据关卡配置先计算目标果蔬的数量再计算干扰项的数量最后用一个Fisher-Yates洗牌算法把所有果蔬位置打乱。这样做避免了一个常见Bug——随机位置重复导致两个果蔬重叠以及目标果蔬全挤在屏幕边缘影响操作的问题。// 简化后的生成逻辑 ListFruitItem GenerateFruits(LevelConfig config) { ListFruitItem fruits new ListFruitItem(); // 先按配置生成目标果蔬 foreach (var target in config.targetList) { for (int i 0; i target.count; i) fruits.Add(CreateFruit(target.type)); } // 再生成干扰项 for (int i 0; i config.distractCount; i) fruits.Add(CreateFruit(GetRandomDistractType())); // Fisher-Yates洗牌 for (int i fruits.Count - 1; i 0; i--) { int j Random.Range(0, i 1); (fruits[i], fruits[j]) (fruits[j], fruits[i]); } return fruits; }对象池洗牌这两个点看起来简单但实际项目里很多人会忽略。我之前做过一个类似的找物游戏一开始没有对象池每关生成30个果蔬、销毁30个用Profiler一跑GC Alloc每帧飙升iPhone 8上掉到30帧。改成对象池之后内存分配几乎归零帧率稳定60。这套源码的设计学院派味道很正可以直接当模板抄。2.3 计分、判定与连击反馈判定逻辑上源码没有用逐帧检测的物理碰撞而是采用点击事件射线检测。每个果蔬挂在同一个父节点下点击时通过EventSystem.current.RaycastAll拿到所有命中的物体再判断点击位置是否在果蔬的Collider2D范围内。计分还有一个细节连击加成。连续3次点对目标果蔬会进入Combo状态得分乘1.5倍同时触发一次全屏闪光特效。这个机制源码里是用ComboCount和ComboTimer实现的void AddCombo() { comboCount; comboDuration 0f; if (comboCount 3) scoreMultiplier 1.5f; else if (comboCount 6) scoreMultiplier 2.0f; }这种在小游戏里特别常见目的就是让玩家在低难度关卡中也能有我真厉害的错觉从而多玩几轮。如果你要把这套源码改造成其他主题比如动物去哪了只需要替换Art目录下的图和Json配置逻辑层完全不用动。3. Unity打包微信小游戏实战记录3.1 环境准备与Unity版本选择打包微信小游戏最头疼的一步是环境配置。这套源码用的是Unity 2022国际版对应微信小游戏适配方案是minigame-unity-webgl-transform这个插件。这里提醒一下Unity 2021以前的老项目直接用minigame插件会出现兼容问题特别是IL2CPP的裁剪和WebGL的渲染管线冲突。如果要复现建议直接装2022.3 LTS版本稳定、坑少。安装完Unity后需要去微信公众平台注册一个小游戏账号个人主体就行拿到AppID。然后在Unity里打开Window - WeChat Mini Game菜单填入AppID设置好输出路径。注意微信开发者工具需要单独下载安装Unity打包本身不会自动打开微信开发者工具两者是独立的。打包完成后需要手动导入到开发者工具中预览。3.2 打包参数配置详解在Unity的Build Settings里按以下参数配置平台选择WebGL压缩格式不要选Brotli选Disable代码优化IL2CPP 大小优先Size图形APIWebGL 2.0不要勾选WebGL 1.0目标解析度适配微信推荐的是750x1334iPhone X比例关键步骤来了用minigame插件提供的WeChat Mini Game菜单直接构建插件会自动帮忙做三件事把WebGL产物转换为小游戏可识别的WX-WASM包自动生成game.json小游戏配置处理启动加载逻辑生成weapp-adapter.js构建完成后在输出目录里会看到webgl文件夹这就是要导入微信开发者工具的内容。第一次构建最常见的坑是构建报错error TS2307: Cannot find module minigame-api-typings。解决方案是在Unity里打开Window - Package Manager搜索minigame安装微信官方提供的类型定义包再重试。3.3 真机预览与调试技巧在微信开发者工具里打开构建产物后点击预览会生成一个二维码手机微信扫码就能真机体验。这里分享一个调试小技巧开发者工具里打开vConsole开关在详情 - 本地设置 - 调试真机上就能看到console.log输出和部分报错信息。真机预览时重点检查三个地方首屏时间从扫码到游戏可交互的时间是否超过3秒触摸响应有没有点击延迟、点击穿透声音播放iOS上首次播放音频是否有延迟这个源码里已经做了首屏优化启动界面只加载一个静态图真正的游戏场景代码用WX.LoadSubpackage按需加载首包只有2.8MB。实测iPhone 11上首屏时间在2.1秒左右普遍过关。4. 好友排行榜的接入与实现4.1 开放数据域原理微信小游戏的好友排行榜不能用普通的Unity GameObject渲染因为它涉及关系链数据微信禁止主域直接访问。官方给出的方案是开放数据域Open Data Context在主域里创建一个独立的CanvassharedCanvas然后通过开放数据域里的TypeScript代码渲染排行榜。听起来绕但理解成两块就通了主域Unity游戏本体只负责把sharedCanvas显示到屏幕上开放数据域一个独立运行的HTML5/TypeScript小程序负责拉取好友数据、画排行榜这套源码在Assets/Plugins/WeChat/OpenData目录下放了一个完整的开放数据域工程里面用到了wx.getFriendCloudStorage接口拉取好友得分数组然后按分数排序列出排行榜。4.2 排行榜渲染与触摸穿透实现具体实现上排行榜不是直接盖在游戏画面上而是放在一个命名为RankPanel的UGUI页面里里面有一个RawImage组件用来显示sharedCanvas的内容。void ShowRankPanel() { rankPanel.SetActive(true); // 请求微信开放数据域刷新排行榜 WX.PostMessage(new WXRankMessage(renderRank)); }在开放数据域里渲染排行榜的核心代码大致如下wx.getFriendCloudStorage({ keyList: [score], success: (res) { const rankData res.data.map(item ({ name: item.nickname, score: item.KVDataList[0] ? item.KVDataList[0].value : 0 })); rankData.sort((a, b) b.score - a.score); drawRankBoard(rankData, canvas); } });需要注意的是触摸穿透问题sharedCanvas只负责渲染不能接收触摸事件。所有点击操作关闭按钮、滚动好友列表都要在主域的UGUI上配置对应的Button和ScrollRect来处理。源码里在RankPanel上挂了一个独立的CanvasGroup和BlockRaycast组件专门拦截事件确保点排行榜的时候不会误触到游戏场景。4.3 排行榜数据上报策略排行榜数据上报用的是wx.setUserCloudStorage源码在每局游戏结束时调用一次void UploadScore(int finalScore) { WX.SetUserCloudStorage($score, finalScore.ToString(), WXGetUserCloudStorageCallback); }这里有个小坑如果玩家每局都上报微信会限频导致部分上报失败。源码的做法是本地存了最高分PlayerPrefs只在分数超过历史最高分时才上报这样既省流量又不会触发限频。5. 资源制作与包体控制优化5.1 图集拆分与纹理压缩格式选择果蔬游戏的素材核心是一堆图标如果每张图独立导入DrawCall会高得吓人。源码的Art目录里已经把所有果蔬图标按类型分成了3个图集Atlas每个图集最多放16张小图并且是512x512正方形的PowerOfTwo尺寸。纹理压缩格式上微信小游戏建议用ASTC格式。但要注意ASTC在低端Android上有兼容风险稳妥的方案是弄两套纹理iOS用ASTCAndroid用ETC2。Unity的AssetBundle是可以按平台分别构建的源码里Build Bundle的功能已经写好了分平台路径。5.2 首包瘦身与远程资源加载微信小游戏对首包大小有硬性要求主包不能超过4MB。这套源码的主包控制在了2.8MB主要靠两点所有大图、音效都放进了AssetBundle做成了远程加载启动场景只包含一个Loading界面和必要的UI图集解读一下AssetBundle的加载逻辑游戏启动后先读取StreamingAssets里的Manifest文件得到一个URL列表再用UnityWebRequestAssetBundle.GetAssetBundle去CDN拉取。这里的核心技巧是Bundle按关卡拆分比如第1-5关共用一个Bundle第6-10关共用一个玩家玩到后面才需要下载新关卡资源这就是所谓的边玩边下。5.3 内存泄漏排查与GC优化休闲小游戏的卡顿大多不是因为逻辑复杂而是GC Alloc太高。这套源码里写了很多避免GC的细节字符串拼接尽量用StringBuilder或直接复用Update里避免创建临时List和Dictionary协程里不要频繁yield return null超过100帧用WaitForSecondsRealtime代替用Unity Profiler实测游戏在真机上运行时GC Alloc稳定在0.5MB/分钟以内这是比较健康的标准。超过2MB/分钟就要警惕了大概率是有频繁的字符串操作或者LINQ查询在产生垃圾。6. 常见问题与排查技巧实录6.1 上线审核常见驳回原因这个项目从开发到过审我踩过的坑集中在这几类问题原因解决方案类目选择错误游戏包含排行榜被误判为社交类目选休闲游戏并在后台关闭好友关系链功能用户隐私协议缺失未声明使用手机存储权限在game.json里配置__usePrivacyCheck__和隐私弹窗首包超过4MB场景内嵌了过多UI图将非首屏资源移到AssetBundle远程加载iOS音频无法播放首次播放音频未在用户点击后触发把AudioSource初始化放在第一次点击回调里6.2 真机加载白屏的排查思路我遇到过最蹊跷的问题是开发者工具里一切正常真机扫码白屏控制台也没报错。后来定位是AssetBundle加载路径不对CDN域名没加白名单。排查步骤分享给大家第一步先看微信开发者工具的Network面板确认AssetBundle请求是否返回200。如果返回304或404说明路径配置有问题。第二步检查后台配置的downloadFile合法域名是否包含CDN的域名。微信小游戏里UnityWebRequest走的其实是wx.downloadFile必须在后台配置合法域名否则会被拦截。第三步如果以上都没问题看WX-WASM的加载时序——在game.json里把showStatusBar临时设成true观察界面是否卡在启动loading页可以分辨是WASM加载失败还是游戏逻辑崩溃。6.3 排行榜数据不同步排行榜有个很损的Bug玩家在A手机得分后B手机上排行榜没变化。这是因为wx.getFriendCloudStorage读的不是实时数据而是有缓存。一般要等10-20秒缓存刷新。如果上线后想强制实时数据可以在游戏结束时同步调一次wx.setUserCloudStorage再在自己的排行榜面板上加一个下拉刷新手势触发WX.PostMessage给开放数据域重新请求。个人习惯是排行榜每次进场景都拉一次但用一个30秒的本地缓存避免频繁请求触发微信的限频机制。如果有个别玩家反馈自己分数没上排行榜多半是最后一次得分没有上报成功这时让玩家重开一局分数超过历史记录就会自动重新上报这个方案很有效。6.4 适配问题iPhone刘海屏与安卓全面屏果蔬图标如果被刘海遮住或者被全面屏裁掉一部分体验会大打折扣。源码里做了一个自定义的SafeArea组件挂在Canvas根节点上运行时读取Screen.safeArea把UI根节点的Rect偏移到安全区域内。RectTransform rectTransform GetComponentRectTransform(); Rect safeArea Screen.safeArea; Vector2 anchorMin safeArea.position; Vector2 anchorMax safeArea.position safeArea.size; anchorMin.x / Screen.width; anchorMin.y / Screen.height; anchorMax.x / Screen.width; anchorMax.y / Screen.height; rectTransform.anchorMin anchorMin; rectTransform.anchorMax anchorMax;安卓全面屏的适配要额外小心很多国产安卓机返回键和手势条会悬浮在游戏底部如果游戏底部有可点击的果蔬很容易出现误触。建议底部留出40像素的净空区或者在检测到Screen.safeArea高度和屏幕高度不一致时把整个游戏场景往上偏移。7. 后续扩展方向与个人心得折腾完这套源码我觉得最值得学习的不只是果蔬生成、对象池这些具体代码而是整个项目的工程化思路配置驱动玩法、平台适配层隔离、开放数据域解耦——这些设计真的是从真实上线项目中沉淀出来的。如果这个项目想继续往下扩展我建议优先考虑两个方向第一个是玩法换皮把这套框架换成动物找茬物品归类等主题美术资源一换就成新游戏第二个是广告变现接入源码里其实预留了Banner广告和插屏广告的接口接入门槛很低真正上线后这也是主要的收入来源。最后再分享一个实操小细节在微信开发者工具里调试时经常会因为缓存导致代码更新不生效只要在编译前勾选清缓存就行。但在真机上遇到类似问题就麻烦了建议在上线前跑一次完整的删除小程序 - 重新扫码打开 - 走一遍核心关卡的流程能提前发现不少缓存和资源版本的坑。希望这份拆解对正在做微信小游戏的朋友有帮助。《果蔬去哪了》这个项目不算复杂但麻雀虽小五脏俱全把启动优化、资源管理、开放数据域、排行榜这些关卡都趟过一遍你已经具备独立上线一款微信小游戏的基础能力了。剩下的就是多写几款、多上线几款踩坑踩出来的经验比看一百篇文章都值钱。本文还有配套的精品资源点击获取