有时,在开发 Unity 软件期间,我们决定改变和改进类、函数和属性 (API) 的工作方式。我们在此过程中尽力对用户现有的游戏代码产生最小的影响,但有时为了力求完美,我们必须做出突破。
从 Unity 的一个重要版本过渡到另一个版本时,我们倾向于仅引入这些重要的“重大改变”,并且仅在可以提高 Unity 的易用性(意味着用户将产生更少的错误)或带来明显性能提升的情况下,而且仅在再三慎重考虑之后,才会做出这些改变。但是,这样做的结果是,如果在 Unity 5 中打开 Unity 4 项目,可能会发现使用的一些脚本命令现在已经被更改、删除或工作方式略有不同。
一个明显的例子是在 Unity 5 中删除了“快速访问器”,以前可以使用这种访问器直接引用游戏对象上的常见组件类型,例如 gameObject.light
、gameObject.camera
、gameObject.audioSource
等等。
在 Unity 5 中,现在必须对所有类型使用 GetComponent 命令(变换组件除外)。因此,如果在 Unity 5 中打开使用 gameObject.light
的 Unity 4 项目,可能会发现特定的代码行已过时而需要更新。
Unity 包含一个 Automatic Obsolete API Updater,可检测脚本中是否使用了过时代码,并且会主动自动更新这些过时代码。如果接受更改,它将使用 API 的更新版本重新编写这些代码。
显然,与往常一样,为了防止出现问题,对工作内容备份非常重要,尤其是在允许该软件重新编写代码的情况下!一旦确定进行了备份,并单击了“Go Ahead”按钮,Unity 便会使用推荐的更新版本重新编写所有过时代码实例。
For example you had a script which did this:
light.color = Color.red;
Unity 的 API Updater 会将其转换为:
GetComponent<Light>().color = Color.red;
更新程序的整体工作流程如下:
1.打开项目/导入包含使用了过时 API 的脚本/程序集的资源包
2.Unity 触发脚本编译
3.API Updater 检查是否存在它知道“可更新”的特定编译器错误
5.如果用户接受更新,则运行 API Updater(这样就会更新以步骤 2 中编译的相同语言所编写的所有脚本)
6.转到步骤 2(考虑所有更新的代码),直到在步骤 5 中没有脚本更新
因此,从上面的列表中可以看到,如果有脚本属于使用过时代码的不同编译过程(例如,不同语言的脚本、编辑器脚本等),则更新程序可能会多次运行。
When the API Updater successfully finishes, the console displays the following notification:
如果选择不允许 API Updater 更新脚本,在控制台中将像往常一样显示脚本错误。还可以看到,API Updater 可自动更新的错误在错误消息中标记为 (UnityUpgradable)。
如果除了使用过时 API 之外,脚本还有其他错误,API Updater 可能无法完全完成其工作,除非修复了其他错误。在这种情况下,控制台窗口中将显示如下消息的通知:
“Some scripts have compilation errors which may prevent obsolete API usages to get updated.Obsolete API updating will continue automatically after these errors get fixed.”
修复脚本中的其他错误后,可以再次运行 API Updater。触发脚本编译时,API Updater 会自动运行,也可以从 Assets 菜单中手动运行,位置如下:
When running Unity in batch mode from the command line, use the -accept-apiupdate
option to allow the API Updater to run. For more information, see Command Line Arguments.
A Version control system helps you see which changes the APIUpdater applies to a Project’s scripts. However, this can be difficult when dealing with pre-compiled assemblies. To see the list of changes made by the AssemblyUpdater (the APIUpdater component responsible for updating assemblies), set the UNITY_ASSEMBLYUPDATE_LOGTHRESHOLD
environment variable to the desirable log threshold and start Unity. For example, on Windows you can enter:
c:> set UNITY_ASSEMBLYUPDATE_LOGTHRESHOLD=Debug
c:> \path\to\unity\Unity.exe
After AssemblyUpdater has finished, you can see the updates that have been applied in the Editor.log:
[AssemblyUpdater] Property access to 'UnityEngine.Rigidbody
UnityEngine.GameObject::get_rigidbody()' in 'System.Void
Test.ClassReferencingObsoleteUnityAPIThroughEditorAssembly::Run()' replaced with 'T
UnityEngine.GameObject::GetComponent<UnityEngine.Rigidbody>()'.
The valid values for the UNITY_ASSEMBLYUPDATE_LOGTHRESHOLD
environment variable are, in increasing order of detail:
Error: The AssemblyUpdater only logs Error messages. Error messages are logged when the AssemblyUpdater fails to apply a specific update, which requires you to take corrective action (usually requesting the original assembly author to provide an updated version of the assembly).
Warning: The AssemblyUpdater only logs Warning, and Error messages. Warning messages usually indicate that the AssemblyUpdater has reached a state that could be a potential problem. These problems can depend on conditions not known to the AssemblyUpdater at the point the message was logged.
Info: The AssemblyUpdater only logs Informational, Warning, and Error messages. Info messages include updates applied by the AssemblyUpdater.
Debug: The AssemblyUpdater logs all messages. Debug help with troubleshooting. You may want to set the threshold to this level if you are having issues with the AssemblyUpdater and you want to report them to Unity.
Error is the default value when UNITY_ASSEMBLYUPDATE_LOGTHRESHOLD
is not set.
如果收到消息“API Updating failed.Check previous console messages”,这意味着 API Updater 遇到了阻止其完成工作的问题。
A common cause of this is if the updater was unable to save its changes - For example - the user may not have rights to modify the updated script because it is write protected.
通过按照指示检查控制台中的前几行,应该能够看到更新过程中出现的问题。
The API updater cannot automatically fix every API change. Generally, API that is upgradable is marked with (UnityUpgradable)
in the obsolete message. For example:
[Obsolete("Foo property has been deprecated. Please use Bar (UnityUpgradable)")]
The API updater only handles APIs marked as (UnityUpgradable)
.
The API updater might not run if the only updatable API in your scripts include component or GameObject common properties, and those scripts only access members of those properties. Examples of common properties are renderer
and rigidbody
, and example members of those properties are rigidbody.mass
and renderer.bounds
. To workaround this, add a dummy method to any of your scripts to trigger the API updater. For example:
private object Dummy(GameObject o) { return o.rigidbody;}.
2018–07–31 Page amended with limited editorial review
Unity 2017.2 中添加了“accept-apiupdate”命令行选项
AssemblyUpdater logging improved in Unity 2018.3 NewIn20183