ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Unity报错Registry configuration is invalid?修复UPM包源与代理配置指南

Unity报错Registry configuration is invalid?修复UPM包源与代理配置指南 项目从同事那儿拷过来或者换了一台新电脑双击Unity加载进度条走到一半弹出一个红底错误框Registry configuration is invalid下面还跟着一行Unable to connect https://packages.unity.cn。你打开Package Manager想看看情况里面全是红叉内置包一个都加载不出来。更离谱的是Unity Hub看起来一切正常项目也能列出就是进不去。直接说结论这个报错不是项目文件损坏也不是电脑硬件有问题而是Unity Package Manager跑到了一个它连不上的包源。重点就在https://packages.unity.cn这个地址上它决定了你的编辑器到底去哪拉依赖包。大多数情况下把源配置恢复、把系统代理处理干净五分钟内就能重新进项目。这篇文章我就按自己踩过坑之后的处理顺序把这条链路完整讲一遍。1. 先搞清楚UPM是怎么去拉包的报错的两条线索1.1 从项目打开到报错中间发生了什么Unity每次打开项目时不只是把场景和代码加载进来它还会同时做一件事解析项目里所有用到的包。这个工作由Unity Package Manager来完成简称UPM。UPM第一步是读取项目目录下的Packages/manifest.json这个文件里记录了两类东西一类是项目依赖了哪些包比如com.unity.textmeshpro、com.unity.postprocessing另一类是自定义Registry的配置用JSON数组写在scopedRegistries字段里。{ dependencies: { com.unity.textmeshpro: 3.0.6, com.unity.ugui: 1.0.0 }, scopedRegistries: [ { name: example, url: https://packages.example.com, scopes: [ com.example ] } ] }然后UPM会根据manifest.json里声明的依赖去找对应的包源。如果某个包没有在scopedRegistries中指定或者所有自定义Registry都不覆盖它UPM就会去访问一个默认Registry。这个默认Registry的地址并不写在项目里而是写在Unity编辑器安装目录的配置文件里。1.2 “Unable to connect”和“Registry configuration is invalid”其实是同一条链路在用词上这两个错误虽然长得不一样但在实际排障中可以合并处理。Unable to connect https://packages.unity.cn的意思是UPM向这个地址发起网络请求但没有建立起有效的连接。可能是TCP握手失败可能是TLS证书验证没过也可能是域名根本解析不了。Registry configuration is invalid的意思是UPM认为某个Registry的配置本身就有问题比如URL不是一个合法地址、JSON格式坏了、缺少必要字段。但很多人会遇到一种特殊情况配置文件本身没毛病只是访问这个Registry时网络网关返回了一个HTML登录页或者空响应UPM解析不了也会报这个错。所以不要再纠结是哪一句本质就是一句话UPM拿不到它想要的包源数据。弄明白这条链路之后你才能理解为什么很多人删掉项目、重新创建项目、甚至重装Unity都没用因为默认Registry的配置存在于编辑器级别的文件里和具体项目没关系。2. 改错地方的典型案例全局配置文件才是真正的“默认源”2.1 项目级与编辑器级两套配置各自管什么我先说一个容易混淆的地方。很多人一看到“包管理”就直奔项目的Packages/manifest.json但改了半天还是报错。这不是你手笨而是manifest.json管的是“项目要装哪些包”和“额外Registry怎么填”它管不到“默认Registry是哪个”。默认Registry的配置在编辑器安装目录下相对路径大概是编辑器安装目录\Editor\Data\Resources\PackageManager\Editor\configuration.json如果你用的是Unity Hub安装那典型路径类似C:\Program Files\Unity\Hub\Editor\2021.3.16f1c1\Editor\Data\Resources\PackageManager\Editor\configuration.json注意版本号里的2021.3.16f1c1那种带c1后缀的版本是Unity中国版。中国版编辑器默认会把registry设置成https://packages.unity.cn目的是让国内网络访问包镜像更快。如果不带c1后缀的国际版默认Registry是https://packages.unity.com。2.2 为什么你的Unity会被指到中国镜像源看到这里你可能会问我根本没改过这个文件为什么我的国际版编辑器也会去连packages.unity.cn很常见原因是编辑器本身就不是官方纯净安装包。网上下载的一些绿色版、整合版、网盘分享版安装包作者在打包前就已经把configuration.json里的源改成中国镜像了或者你在看某个教程时跟着别人复制了命令行或者配置文件去加速包下载自己也忘了这回事。不管哪种情况一旦这台机器所在网络访问packages.unity.cn不稳定或者该域名解析到了不可达的IP启动项目时就会弹出那个红底错误。2.3 修改配置文件前你必须知道的三件事修改这个文件本身不难但有三个细节很容易翻车。第一编辑器必须完全退出包括Unity Hub后台不要挂着否则你的修改可能被编辑器退出时的配置写回覆盖掉。第二不要用Windows自带的记事本直接编辑。记事本保存时默认会带UTF-8 BOM而Unity某些版本对带BOM的JSON配置文件解析有问题改了之后反而会多出“Registry configuration is invalid”。用VS Code或者Notepad保存时选择“UTF-8无BOM”这个坑我碰到过不止一次。第三改之前先备份原文件把原文件复制一份改成configuration.json.bak放在旁边。虽然改错了可以回头查文档但有个备份心里不慌。改法很简单找到文件里的registry字段把值改成官方源{ registry: https://packages.unity.com, enablePackageManagerTraces: false }如果没有registry字段就在最外层JSON对象里自己加上。不同Unity小版本这个文件里带的字段可能不太一样但UPM的读取逻辑基本兼容加上这一行是安全的。3. 最简修复链路四步固定排查法3.1 第一步验证域名和端口到底通不通一切不谈网络状态的配置修改都是瞎猜。修改配置文件之前先花一分钟确认连通性。在Windows上打开CMD或PowerShell依次执行三条命令curl -I --connect-timeout 5 https://packages.unity.cnnslookup packages.unity.cnTest-NetConnection packages.unity.cn -Port 443curl命令如果能返回HTTP头哪怕是一个302重定向都说明域名解析、TCP建连、TLS握手都正常。如果超时或者报错那就说明问题在网络层不在配置层。nslookup能告诉你域名解析到了哪个IP如果解析出来的IP不是预期中的就需要查hosts文件和DNS设置。Test-NetConnection的结果比较直接TcpTestSucceeded : True就是端口通。这条命令很重要因为我曾经见过有人花了一晚上改配置最后发现是局域网DNS缓存了旧IP。3.2 第二步系统代理和HTTP/HTTPS环境变量检查排第一位的网络“元凶”是系统代理。Unity编辑器和Unity Hub会读取Windows系统的代理设置同时也会读取用户环境变量里的HTTP_PROXY、HTTPS_PROXY、ALL_PROXY。这里有个很隐蔽的坑很多时候你之前用过某个本地代理工具工具卸载了或没启动但系统代理开关还开着代理地址填着127.0.0.1:1080之类的本地端口。Unity去访问包源时会把请求发到这个根本没有服务的端口上结果自然是连接失败。在CMD里执行echo %HTTP_PROXY% echo %HTTPS_PROXY%如果有输出尤其是指向本地端口的先记下来然后去Windows设置里关掉“使用代理服务器”再到系统环境变量里删掉这两个变量。删完之后重启Unity Hub和Unity编辑器再试。如果你确实需要代理才能访问某些网络那不要在这里硬删而是把packages.unity.cn和packages.unity.com加入NO_PROXY环境变量里这样UPM请求会绕过代理直连。3.3 第三步恢复默认源还是换官方源如果网络确认通了那就进入配置修改阶段。中国版编辑器或之前被改过配置的编辑器直接改回官方源是最省事的。按第2节的方法改configuration.json保存后重新打开Unity。改完之后可以顺手把项目下的Packages/packages-lock.json备份一下再删掉。这个文件是UPM的依赖锁文件记录了解析过的包的精确版本和来源。删掉之后重新打开项目UPM会重新解析依赖并重建锁文件这能解决一部分旧锁文件和当前Registry不一致的问题。注意删除Library文件夹不是好主意。新手看到项目坏了就喜欢删Library但这个文件夹里包含了所有包的本地缓存Library/PackageCache一旦删掉UPM必须联网把所有依赖包重新下载一遍。现在你就是在跟Registry连接出问题的场景下等于自己把退路断了。3.4 第四步重启编辑器并强制Package Manager刷新配置改完、锁文件清理完之后重新打开项目。进入编辑器后打开Window Package Manager点击左上角包源下拉菜单看一下当前选的是哪个源。点击窗口左下角或者齿轮图标里的Refresh强制UPM重新拉取包列表。正常的流程应该是Package Manager里不再飘红内置包全部显示出来依赖包正常加载。如果此时项目脚本因为缺少包而报编译错误等包恢复后重新编译即可。为了帮助你对照我把常见症状、原因和处理办法整理成一个简单表格表现常见原因处理方向报Unable to connect域名不通、代理失效、DNS解析错误查网络代理、hosts、DNS报Registry configuration is invalid配置文件被改坏、返回非JSON恢复官方源、检查JSON编码能开项目但Package Manager反复转圈网络慢、缓存不全等超时或换可达源只有部分包报错某个scoped registry挂了检查manifest.json自定义源是否正确4. 如果网络注定不通离线缓存和本地包方案4.1 把另一台机器的全局缓存整个搬过来有的场景下不是配置写错了而是目标机器所在网络确实访问不了外网包源。比如公司内网开发机安全策略限制得非常严格。这时候再改源也没用因为哪个源都不通。有一个很实用的办法在你手头另一台能访问包源的机器上找到Unity包管理器缓存目录默认是C:\Users\用户名\AppData\Local\Unity\cache\npm\这个目录下面会按照域名分成好几个子目录比如packages.unity.cn、packages.unity.com里面是UPM下载过的所有包文件。你把这整个npm目录原封不动拷到目标机器上的同路径下。UPM在解析依赖时会优先检查本地缓存中是否已经有对应版本。只要缓存里的包版本和manifest.json要求的一致它就可以在断网状态下直接把包从缓存中载入项目从而绕过网络请求。有两个细节要注意拷贝之前先确认目标机器的Unity配置文件中registry指向哪个域名缓存子目录名字要与之匹配如果项目要求某个包的新版本而缓存里没有断网状态下依然会失败。4.2 只差一两个包时用本地tarball最省事全量缓存搬运适合整机拷贝但如果你只是某个项目依赖了一两个特定包完全没必要搬几GB缓存。在有网机器上打开Package Manager找到目标包点右上角的下载箭头导出.tgz文件。把这个文件拷到目标机器后修改项目Packages/manifest.json把对应依赖项的值改成本地文件路径{ dependencies: { com.unity.textmeshpro: file:C:/LocalPackages/com.unity.textmeshpro-3.0.6.tgz } }注意路径中的斜杠方向Windows下推荐使用正斜杠避免转义问题。这样UPM会直接从本地文件安装包完全不触发网络请求。4.3 团队内网可以自建一个私有Registry如果你是一个前端工程师出身听到UPM可能有点陌生但它依赖的那套机制本质上是npm生态的变体。UPM的Registry返回的是标准的npm包元数据和tarball。所以团队成员比较多、长期有包下载需求的团队可以用Verdaccio在内网搭一个私有源。大致思路是在内网一台服务器上安装Node.js环境用npm安装Verdaccio启动后把默认上游Registry指向https://packages.unity.com或https://packages.unity.cn。然后在每台开发机的Unity里配置自建源地址。这样所有成员共享同一份包缓存下载速度飞快也不用每个人各自跟外网斗智斗勇。这个方案适合工程团队不适合个人临时解决问题。个人用户当前遇到问题直接用前两种方案已经足够。5. 对照自查的真实坑位每一条都是我实际遇到过的5.1 hosts文件里的“历史遗留问题”排查到后面很多人都忘了Windows还有一个hosts文件。我遇到过一台机器hosts里有一行几年前为了测试留下的packages.unity.cn指向127.0.0.1结果Unity每次访问该域名都被解析回本机当然连不上。排查方法很简单打开C:\Windows\System32\drivers\etc\hosts搜索packages.unity任何相关记录先注释掉或删掉保存后执行ipconfig /flushdns刷新DNS缓存。5.2 系统代理开着但没有代理进程这个在3.2节提过但我觉得值得再强调一次因为它的隐蔽性太高了。Windows系统代理那里开着“使用代理服务器”地址是127.0.0.1:7890但电脑上根本没有软件监听这个端口。浏览器可能因为你没开某个插件而上不了网但至少浏览器会明确告诉你“无法访问此网站”。Unity呢它只是默默地在后台连不上包源最后给你一个模棱两可的Registry错误。遇到顽固问题先把代理开关关掉再测。不信你可以做个实验开一个不存在的代理端口然后打开Unity项目基本上百分百复现这个报错。5.3 杀毒软件或上网行为管理拦截Unity联网还有一种情况是curl能通、浏览器能通、但Unity就是不行。这种时候要先想想机器上有没有装什么安全软件或公司统一的上网行为管理客户端。UPM用的是编辑器自带的HTTP栈不走浏览器的网络栈行为管理软件对它不熟悉可能直接拦截了。表现就是其他程序都能上网唯独Unity连外网失败。处理办法是到杀毒软件或防火墙设置里把编辑器目录下的Unity.exe加入白名单并允许它在专用网络和公用网络上通信。如果机器是公司统一管理的可能需要联系IT支持处理。5.4 系统时间偏差导致TLS握手失败最后一个坑也是最少有人想到的TLS证书校验。HTTPS连接建立时客户端会校验服务器证书的有效期而判断有效期靠的是本机系统时间。如果系统时间比实际时间偏了好几天证书会被认为“尚未生效”或“已经过期”握手失败最终体现为Unable to connect。这种情况在那些长期不联网、或者使用老化主板的机器上出现的概率不低。手动把系统时间改正确自动同步一次之后问题可能就莫名其妙消失了。排查时你可以在PowerShell里执行Get-Date如果显示的日期时间和当前实际时间差超过几分钟先同步时间再说。5.5 真正的终极排查手段看Editor.log如果你把所有方法都试了一遍还是不行通常情况下问题就出在不太常规的地方。这时候与其瞎猜不如让Unity自己告诉你它到底干了什么。找到编辑器日志文件路径是C:\Users\用户名\AppData\Local\Unity\Editor\Editor.log用文本编辑器打开搜索Package Manager或者报错里的Registry域名你会看到UPM每一次请求的URL、状态码、耗时。它会直白地告诉你是DNS解析失败、连接超时还是服务器返回了401、403、503。到了这一步问题定位基本就是板上钉钉了。我自己踩过最深刻的一坑是折腾了很久发现Editor.log里显示UPM请求时带了旧的代理头根源是环境变量HTTP_PROXY里有一个看不见的尾部空格。你永远想不到一次手动配置能埋下多少雷所以遇到类似问题别急着骂Unity先让日志说话。
返回列表