
最近在给一个 Unity 微信小游戏项目接云函数时又撞上了“cloudfunctions 未选择环境”这个提示。这个报错我前前后后踩过好几次网上的帖子大多只甩一句“去选一下环境就行了”但具体在哪选、怎么选、选了之后怎么保证不反弹都没说透。尤其到了 Unity 导出小游戏打包的场景情况会更隐蔽。这篇文章就把我从现象到解决方法的完整链路捋一遍包括开发者工具里的操作、代码里的显式配置以及 Unity 打包后的特殊处理希望能帮同样卡在这里的人少走点弯路。1. 先搞清楚“未选择环境”到底是在哪一层报出来的1.1 云开发环境是什么为什么云函数离不开环境微信云开发里“环境”是一个资源隔离的单位可以理解成一台独立部署的小后端集群。每个环境都有自己独立的数据库、存储空间、云函数列表甚至独立的安全规则。环境之间互不相通环境ID就是访问这些资源的“钥匙”。云函数在运行的时候需要一个明确的上下文告诉它“你归属于哪个环境”。这个上下文决定了它能访问哪个数据库、哪份存储也决定了客户端调用它时要走哪个资源通道。如果上下文是空的云函数就没有办法定位资源于是系统只能在初始化或部署阶段拦一道提示“未选择环境”。换句话说这不是云函数写错了而是运行环境和调用环境没有对上号。微信开发者工具里“未选择环境”可能出现在两个层面的地方一是云开发控制台的顶部显示当前环境是“未选择环境”二是在 cloudfunctions 目录上右键上传部署时工具校验不到环境信息。还有第三种场景就是代码本身没有传递 env 参数导致云函数在客户端调用时直接报错。很多人把这三者混为一谈所以怎么都修不好。1.2 我遇到的“未选择环境”现场与两种常见触发路径先说第一种触发路径我新建了一个微信小游戏项目还没开通云开发直接在工程里塞了个云函数目录然后在 cloudfunctions 目录上右键“上传并部署”工具弹窗提示“请先选择环境”。这个时候去云开发控制台看当前环境确实显示“未选择环境”因为后台压根没有环境可选。这种属于基础环境没有创建。第二种触发路径更常见也更容易让人崩溃项目是一个 Unity 微信小游戏打包产物通过构建工具把 WebGL 转成了小游戏结构云函数已经部署在云端了IDE 的环境选择也能看到环境但运行时调用 wx.cloud.callFunction 就是不稳定时而提示“未选择环境”时而提示“env not found”。后来我定位到是 Unity 导出后生成的 game.js 里虽然保留了 wx.cloud 相关代码但初始化时没有传 env而 IDE 的“当前环境”只是在开发者工具层面作为默认值产物里的代码如果不主动传运行环境会拿不到有效值。这两种路径其实都指向同一个结论必须在代码层面把环境ID固定下来IDE 选择环境只是辅助。2. 云函数环境设置的标准操作从IDE到代码全打通2.1 第一步开通云开发并创建环境在微信开发者工具中工具栏上有一个“云开发”按钮。点击后如果没有开通过云开发会进入开通引导界面需要选择云开发基础功能。我建议直接把环境创建这一步也完成因为后面部署云函数必须有环境。创建环境时系统会生成一个环境ID形如cloud1-xxxxxxx或者类似的自定义字符串。在云开发控制台首页右上角可以进入环境设置那里能看到当前账号下的所有环境ID。这个环境ID非常重要后面代码初始化就靠它。如果你手里有多个项目最好给每个项目单独创建环境避免环境混用导致数据和云函数互相串。这里有一个很容易犯的细节创建环境后有一个“安全域名”之类的配置小游戏项目要注意在云开发控制台里把当前的小游戏 AppID 加入到白名单否则环境创建了也无法正常调用。不过大多数情况下首次创建环境时系统会默认把当前项目加入跨 AppID 使用云开发环境时才需要手动处理。2.2 第二步在开发者工具里把当前环境选对环境创建好了之后回到开发者工具。在工具栏“云开发”按钮附近会有一个环境选择的下拉框默认可能显示“未选择环境”。点击下拉框选择你刚创建的那个环境。这一步属于“IDE 层面的绑定”作用是在你打开云开发控制台、查看数据库或调试云函数时工具知道该展示哪个环境的数据。如果下拉框里看不到任何环境先检查一下你是不是用对了 AppID。云开发环境是跟小程序/小游戏 AppID 绑定的普通测试号可能没有云开发能力需要换成注册过的 AppID。也检查一下开发者工具是否登录了正确的小程序账号某些账号没有管理员权限时云开发面板也会一片空白。选中环境之后建议重启一下开发者工具让配置彻底生效。说实话微信开发者工具在环境选择这块的缓存做得不算稳定我遇到过明明选了环境关闭项目重新打开后又回到“未选择”的情况。重启工具能解决一大部分这种假性未选择问题。2.3 第三步在代码里把环境ID写死别靠自动匹配IDE 选环境只是给开发者自己看的真正决定云函数运行环境的是代码里的初始化语句。这也是“未选择环境”最隐蔽的元凶——你觉得已经选好环境了但产物代码里没有指定实际调用时还是找不到。在小游戏项目的入口代码中原生项目一般是app.js或game.jsUnity 导出的小游戏也是game.js但逻辑可能被压缩过需要出现类似以下的初始化代码wx.cloud.init({ env: 你的环境ID, traceUser: true });这段代码要放在调用云函数之前执行最好只执行一次。注意env字段必须传环境ID不是环境名称。环境ID在云开发控制台的环境设置里可以复制千万别手打手打容易漏字符或者混入空格到时候排查半天也找不到问题。如果本来就已经有wx.cloud.init()但没有env字段那就需要补上。很多 Unity 导出的项目保留了这段调用但参数是空的我看过好几个导出产物初始化代码长这样wx.cloud.init({ traceUser: true })这种写法在开发者工具里依赖 IDE 选择的“默认环境”偶尔能跑通但一旦 IDE 当前环境没有正确匹配运行时就变成“未选择环境”。所以我的习惯是所有项目一律显式传env不给它猜的机会。3. 设置环境时最容易踩的四个坑3.1 环境列表是空的什么都选不了如果你点击环境下拉框里面空空如也多半是下面四种情况之一当前项目还没有开通云开发要先去云开发控制台完成开通。云开发已经开通但没在控制台里创建环境需要手动创建。开发者工具登录的账号没有该环境所在项目的权限。开发者工具版本过旧云开发面板没有正常加载重启工具或者升级到最新版本试试。我遇到最多的是第一种。很多新手拿到一个带云函数目录的示例项目第一反应直接在 cloudfunctions 上右键部署结果连环境都没有工具自然报“未选择环境”。先把环境创建出来这一步就解决了八成问题。3.2 明明选了环境一上传又变“未选择”这种情况我踩过两次。第一次是我选完环境后因为项目里配置了多个云函数目录右键上传时没看目录归属又把根目录下的云函数传到了错误的地方。第二次是开发者工具的本地缓存问题环境选择结果没有写入到工程配置文件中。针对缓存问题可以在开发者工具菜单里找到“清除全部缓存”之类的选项清完重新编译再重新选择一次环境基本能解决。另外检查一下project.config.json里的cloudfunctionRoot配置是否正确指向了 cloudfunctions 目录。有些 Unity 导出项目会自动生成一个project.config.json里面的cloudfunctionRoot可能缺失导致工具无法识别云函数目录也会连带出现环境识别异常。3.3 多环境下云函数跑到了别人的数据库里这个坑很有意思。当一个微信小游戏关联了多个云开发环境时IDE 默认会选第一个环境但你的云函数可能部署在第二个环境。如果你在 IDE 里选了第二个环境但客户端代码里没写env那么有些情况下调用链会出错。更危险的是云函数部署在环境A客户端的wx.cloud.init没传 env系统可能自动匹配到了环境B导致云函数确实能调用但数据库读写的是环境B的数据而环境B里可能根本没有对应的集合于是一堆操作悄悄失败。这种问题表面上看不是“未选择环境”但根源跟环境没绑死是相同的。我建议的做法是在cloudfunctions/目录下给每个云函数都维护一份环境变量的说明或者在一个统一配置模块里定义环境ID。实在不行就在代码里写死简单粗暴但有效。3.4 调用云函数时返回 invalid env 或环境错误这种情况下IDE 可能显示环境已经选定但运行时报 “invalid env” 或类似的“环境不合法”信息。排查看这里检查env是否真的是环境ID而不是环境名称。环境名称是给人看的环境ID才是代码用的。检查复制环境ID时是否有多余的空格、换行。检查环境ID是不是删错了环境导致 ID 不存在。检查云函数是否真的部署到了指定的环境。有些人在工具上有多个项目部署时传错了项目环境对不上也会报错。这类故障排查时我的第一反应永远是在控制台里找到环境ID复制然后粘贴到代码里不要手打。如果你已经粘贴了可以删掉重新粘贴一次因为有时候从某个文档复制出来的环境ID可能包含了不可见字符。下面整理了一个速查表方便直接对着排查现象可能原因快速处理环境下拉框为空未开通云开发/未创建环境进入云开发控制台创建环境下拉框为空且开通不了AppID无云开发权限换成已注册的AppID或开通云开发服务选择后重启又变未选择工具缓存问题清缓存并重启开发者工具选了环境但上传仍报错当前上传目录与所选环境不一致确认右键部署的是目标环境下的云函数运行时报invalid env代码中env未填或填错复制正确的环境ID填入wx.cloud.init调云函数用的数据库不对代码未固定env导致自动匹配错环境在wx.cloud.init中显式传env4. Unity 微信小游戏打包后同样会遇到这个问题4.1 Unity 导出的小游戏项目结构里云环境配置在哪里Unity 项目导出微信小游戏核心行为了解一下Unity 会通过 WebGL 编译出代码和资源封装成小游戏可运行的包产物在build/wechatgame目录下里面有game.js、game.json、project.config.json等文件。云开发相关的逻辑Unity 导出时并不会自动生成它是从你的 Unity 工程的 C# 业务代码中调用适配层转换为 JS 运行时 API 的。如果你的 Unity 工程中使用了云开发相关插件或自己封装了wx.cloud调用那导出的game.js里会保留对应的初始化代码。搜索cloud.init或者wx.cloud就能定位到。如果搜不到说明 Unity 工程里根本没有接入云开发那自然会在运行时出现“未选择环境”或“cloud is not defined”之类的错误。所以 Unity 打包场景下的“未选择环境”多数不是环境选择框的问题而是导出产物里缺少正确的环境初始化。4.2 Unity 项目接入云开发时如何提前绑定环境在 Unity 侧我建议把云环境ID做成一个配置项放到一个公共静态类里后续导出直接跟随代码进入game.js。例如public static class CloudConfig { public static string EnvId 你的环境ID; }在使用云函数前通过适配层调用一次初始化。具体调用方式取决于你用的是什么打包插件有的是 Registry 里暴露wx.cloud.init有的是在启动场景里执行一个入口脚本。只要保证 Unity 逻辑在导出后能在game.js对应位置生成一行类似wx.cloud.init({ env: 你的环境ID })的代码即可。这里提醒一点Unity 里你如果直接写死环境ID每次切环境都要改代码容易漏。最好做一个环境切换的编辑器工具在打包前通过菜单选择线上/测试环境自动替换对应的环境ID。这个在多人合作或者多环境并行测试时特别实用。4.3 打包后补救直接在产物里改初始化代码如果你已经导出了小游戏又不想重新从 Unity 打包可以直接在build/wechatgame/game.js里搜索cloud.init然后把环境ID补进去。Unity 导出的game.js一般是压缩过的但云函数的初始化代码通常可读性还不算太差。定位到wx.cloud.init所在的位置给参数对象加上env字段。需要注意的是改完game.js后建议重新在微信开发者工具中编译预览。如果项目开启了某个 MD5 或者远程资源加载game.js可能被缓存需要清缓存处理。这种直接改产物的方式适合救急但不适合长期维护因为一旦重新从 Unity 导出改动就会被覆盖。长期运维还是建议在 Unity 工程内部解决。还有一个小细节Unity 微信小游戏打包时云函数目录同样需要在project.config.json里通过cloudfunctionRoot指定。如果你在 Unity 工程里提供了云函数源码却忘了把目录名配置上打包后开发者工具同样无法识别云函数进而出现环境不匹配。检查project.config.json中的cloudfunctionRoot是否指向了包含云函数的目录这个字段的值通常类似于cloudfunctions/。5. 从这个问题延伸出来的排查思路与习惯5.1 判断云函数是否正常运行的三个验证点环境问题解决后怎么确认云函数真的跑通了我一般按三个层次来验证。第一个层次云函数能不能在控制台手动运行。在云开发控制台找到对应云函数点测试能正常返回结果说明函数本身没有问题。第二个层次IDE 里本地调试能不能跑通。右键云函数选择“本地调试”如果可用看是否能正常连接云端资源。这一步能验证本地代码与云环境的连通性。第三个层次从小游戏端发起真实调用。在小游戏中触发业务逻辑看wx.cloud.callFunction是否返回预期数据并且确认数据库/存储读写都发生在目标环境。如果没有环境隔离概念可以在两个环境里分别创建不同的测试集合调用后看看到底连了哪个环境一目了然。5.2 我自己的环境配置工作流踩了多次坑之后我现在处理云函数环境会按照下面这套流程来强烈建议你照抄一遍先在云开发控制台创建环境复制环境ID粘贴到一个统一配置文件中。然后在项目入口代码中显式调用wx.cloud.init固定env。再回到开发者工具在环境选择下拉框中选中同一个环境。最后部署云函数控制台测试客户端全链路验证。这套流程里最关键的就是“统一配置 显式传参”。我见过太多人只做 IDE 选择不写代码参数结果换个环境、重导一下项目问题就原形毕露。像我之前带的一个新人遇到“未选择环境”只会反复切换下拉框切换十次都没用。我让他代码里补上 env一分钟搞定。另外一个小技巧如果你在排查环境问题时反复改动代码一定要留意控制台的日志输出。微信开发者工具的调试器里云环境相关的错误日志通常会带环境ID或错误码截图搜一下往往比瞎猜高效得多。尤其是 Unity 打包产物报错信息不一定来自游戏逻辑可能来自底层适配层多看日志能少走很多弯路。这个“未选择环境”本身不难解决难的是它可能出现在 IDE、代码、产物三个不同层面而且每个层面处理方式不一样。希望这篇文章能把微信小游戏云函数的这个坑给你填平下次再遇到直接按着上面的流程走一遍就行。