Unity 版本支持
HEXR 支持哪些 Unity 版本,以及升级编辑器后项目无法编译时如何排查。
HEXR 支持的 Unity 版本
插件包声明了 "unity": "2022.3",同一套代码可在 Unity 2022.3 LTS 至 Unity 6000.6 上运行,无需为不同的编辑器版本准备单独的分支或插件包。
| Unity | 状态 |
|---|---|
| 2022.3 LTS | 支持——声明的最低版本 |
| 2023.2 | 支持——已验证插件包程序集可以编译,无错误,也无弃用警告 |
| Unity 6(6000.x),至 6000.5 | 支持——验证方式同上 |
| 6000.6 | 支持——两个教程项目均使用 6000.6.0f1 基于 0.9.3 构建,0.9.4 也能在该版本上编译,且编辑模式测试全部通过 |
| 更高版本 | 尚未验证。可能遇到的问题请参阅升级为何会出问题 |
Unity 升级后,出问题的往往是你的 XR 后端,而不是 HEXR。尤其是 Meta XR SDK,它绑定了特定的编辑器版本范围,版本搭配不对会导致整个项目无法编译——连与它毫不相关的代码也会受影响。在认定问题出在 HEXR 之前,请先阅读Meta XR SDK 版本搭配。
为什么升级 Unity 会导致插件包出错
Unity 分两个阶段淘汰 API,项目往往就是在这两个阶段之间出的问题。
第一阶段:变为警告
该方法仍然可用。编译器报出 CS0618,控制台显示黄色警告。由于一切正常,几乎所有人都会忽略它。
若干版本之后:变为错误
Unity 将同一特性(attribute)改为错误级别。此时编译器报出 CS0619,程序集无法再构建。代码本身没有任何改动——变的只是编辑器。
最可能影响 Meta 项目的例子:Object.GetInstanceID() 在多个版本中一直只是警告,到 Unity 6000.3 变成了硬性错误,改用 GetEntityId() 替代。任何仍在调用它的插件包,升级后都无法编译。
Unity 升级后出现的黄色警告并不是噪音——它们列出的正是下一次升级时会变成构建错误的内容。趁它们还是警告时就清理掉,远比等到它们阻塞构建时再处理省事。
第 1 步:确定是谁的代码出错
这是最有用的排查步骤,只需看一眼错误中的文件路径。请在阅读错误信息之前先做这一步。
| 错误中的路径 | 代码归属 | 你能做什么 |
|---|---|---|
Library/PackageCache/… | 第三方插件包——Meta XR SDK 或某个 Unity 插件包 | 编辑该文件无法解决问题。它是会重新生成的缓存,下次重新导入时你的修改就会被清除。请改为更换插件包版本 |
Packages/… | 嵌入式插件包,包括以内嵌(vendored)方式放入项目的 HEXR | 可编辑且修改会保留,但这相当于派生(fork)了一份——下次更新插件包时修改会丢失 |
Assets/… | 你自己的代码 | 直接修复 |
如果所有错误都位于 Library/PackageCache 下,那么在你自己的脚本上花再多功夫也无济于事。解决方法是更换版本。
第 2 步:解读编译器错误
Unity 会直接显示 C# 编译器的原始错误代码。通过错误代码,就能判断你遇到的是哪一类版本不匹配。
| 错误代码 | 含义 | 升级后的常见原因 |
|---|---|---|
CS0619 | API 已过时,并且被标记为错误 | 你的编辑器版本比插件包预期的更新。必须更新插件包——这类错误无法屏蔽 |
CS0618 | API 已过时,仅为警告 | 仍可构建。这是你下次升级前的预警清单 |
CS1061 / CS0117 | 该类型没有此成员 | 你的编辑器版本比代码预期的更旧——该成员尚不存在。请降级插件包或升级编辑器 |
CS1503 | 参数类型不匹配 | 所调用的重载是在更高版本中才加入的 |
CS0246 | 找不到类型或命名空间 | 完全缺少某个插件包,或未引用其程序集定义 |
#pragma warning disable 和编译器开关 -nowarn 只对警告有效。CS0619 是错误,所以两者都对它无效。网上教你屏蔽它的建议,其实针对的是 CS0618。要解决 CS0619,只能修改代码或更换版本,别无他法。
第 3 步:按正确顺序修复
Unity 按依赖顺序编译程序集,并且在第一个失败的程序集处停止。所有依赖它的程序集都不会被编译,因此它们的错误也不会显示出来。
这一点比听起来更重要。控制台显示三个错误,并不意味着只有三个问题——那只是第一个失败的程序集,后面可能还有多得多的错误在等着。修复已报告的错误,重新编译,再看会出现什么。不要根据第一次的控制台输出来估计工作量。
从依赖链的底层往上修复:先修 XR 后端,再修 HEXR,最后修你自己的脚本。
Meta XR SDK 版本搭配
Meta XR SDK 绑定特定的编辑器版本范围,Meta 为每个范围分别发布不同的 SDK 版本线。版本搭配错误是 Meta 项目升级后无法编译的最常见原因,而且错误全都出现在 Library/PackageCache/com.meta.xr.… 中——与你自己的代码毫不相干。
先检查版本搭配:打开 Packages/manifest.json,将 com.meta.xr.sdk.all 与该 SDK 自身 package.json 中的 "unity" 字段进行对比。如果 SDK 写的是 2022.3,而你运行的是 Unity 6,问题就在这里。
Meta 的各个插件包都是 com.meta.xr.sdk.all 的传递依赖。只需在 manifest.json 中升级这一项,Unity 就会重新解析其余依赖。然后关闭编辑器,删除 Library/PackageCache/com.meta.xr.*,再重新打开,让缓存重新生成。
HEXR 如何保持版本中立
在支持范围内存在差异的所有引擎 API,都统一经由一个文件 Runtime/HexR/HexRCompat.cs 调用。版本判断只写在这里,别处没有,因此当 Unity 淘汰某个 API 时,只需在一个地方改一行,而不必在整个插件包中四处查找。
这种做法值得在你自己的代码中借鉴。目前它涵盖的内容如下:
| Unity API | 问题 | HEXR 调用 |
|---|---|---|
FindObjectOfType, FindObjectsOfType | 自 2023.1 起弃用 | HexRCompat.FindAny / FindAll |
FindObjectsSortMode | 6000.4 及之前正常,6000.5 中弃用 | HexRCompat.FindAll |
Rigidbody.velocity | 在 Unity 6 中更名为 linearVelocity;在此之前的版本中不存在这个新名称 | HexRCompat.GetLinearVelocity / SetLinearVelocity |
在 6000.5 之前,场景搜索返回的对象按 InstanceID 排序。从 6000.5 开始,由于 InstanceID 正逐步被 EntityId 取代,Unity 取消了这一保证。如果场景中有两个对象同名,按名称查找时找到的是哪一个,在旧版编辑器上是确定的,在 6000.5 及以上版本中则是任意的。请为对象设置唯一的名称,不要依赖旧的排序。
升级前检查 API
你不必安装编辑器,就能知道它会不会让你的项目出问题。每个 Unity 安装都自带参考程序集和 C# 编译器,因此你可以针对磁盘上已有的任意版本编译几行代码,读取真实的诊断信息——与 Unity 输出的完全相同。
把你不确定的调用写进一个小文件,然后用该编辑器的程序集编译它:
# Point this at the editor you want to test against
UNITY="C:/Program Files/Unity/Hub/Editor/6000.5.7f1/Editor/Data"
DOTNET="$UNITY/DotNetSdk/dotnet.exe"
CSC="$UNITY/DotNetSdk/sdk/8.0.318/Roslyn/bincore/csc.dll"
REFS="$UNITY/Managed/UnityEngine"
"$DOTNET" "$CSC" -nostdlib+ -target:library -out:probe.dll Probe.cs -r:"$UNITY/NetStandard/ref/2.1.0/netstandard.dll" -r:"$REFS/UnityEngine.CoreModule.dll" -r:"$REFS/UnityEngine.PhysicsModule.dll"输出结果会准确告诉你每个调用处于淘汰周期的哪个阶段——正常、CS0618 还是 CS0619——让你在决定升级之前就心中有数。本页的支持表也是这样得出的。
向我们报告版本问题
如果 HEXR 本身无法在你的编辑器上编译,报告中包含以下信息能让我们最快处理:
| 内容 | 获取位置 |
|---|---|
| 确切的编辑器版本 | ProjectSettings/ProjectVersion.txt——完整字符串,例如 6000.5.7f1 |
| HEXR 插件包版本 | 插件包 package.json 中的 "version" 字段 |
| 你的 XR 后端及其版本 | Packages/manifest.json |
| 最先出现的错误及其文件路径 | Unity 控制台。路径与错误信息同样重要——它们表明是谁的代码出了错 |
请通过联系我们页面发送。如果控制台截图裁掉了文件路径,我们就无从下手。