Skip to main content

UdonSharp 的前世今生

你好,来自现实的旅人 ${ LocalPlayer.displayName }

欢迎来到 UdonSharp 的世界。

// TODO 此处应该有饱含人文关怀的序以安抚被 UdonSharp 伤透了心的可怜新手开发者

UdonSharp 的前世

相关时间线:

VRCSDK 2 时代

在 VRCSDK 2 时代,想要为地图实现动态功能,唯一的工具是 VRC_Trigger 脚本。它可以响应 Unity 组件的回调并进行一些操作,例如修改 Animator 参数值等,但无法实现更为复杂的功能。社区需要新的工具为世界增加更多功能。

在此背景下,VRChat 开发团队决定内部研究 PlayMaker 这一第三方工具集的集成。但随着 VRChat 开发团队的壮大,以及经过内部测试人员的讨论,VRChat 开发团队决定不应该依赖第三方工具,而是开发自己的“功能强大、由 VRChat 编写的免费定制工具包”。根据 VRChat 的博客,该工具包称之为 VRChat “Node Graph”。也许是因为 Shader Forge、Amplify Shader Editor 这样使用基于“节点”的编程方式的工具的流行,VRChat 也决定使用类似的可视化编程方案。

Udon乌冬面 的诞生

随着 VRChat 2020.1.1p1 的发布,VRChat 正式支持新的世界编程工具 Udon。取代 VRCSDK 2 的 VRC_Trigger 脚本的是被称为 Udon Node Graph 的基于节点的可视化编程工具。Udon Node Graph 会被编译为 Udon 字节码,字节码将被 Udon VM 这一解释器解释执行。高级用户还可以自行编写 Udon 汇编或直接生成 Udon 字节码。

在 Udon Node Graph 伴随 VRCSDK 3 推出后,部分 VRCSDK 2.0 用户对此很不满,理由是 Udon Node Graph 并不好用,也不符合  VRCSDK 2.0 用户的旧习惯。社区开发者 CyanLaser 为此在开发了闭源的类 VRCSDK 2 风格的 Udon 编译器 CyanTrigger,。这部分用户继续停留在 VRCSDK 2 或 使用替代品 CyanTrigger,Udon Node Graph 并没有被重视 // TODO Udon Node Graph 的限制和用户反应

// 此处应该有 CyanTrigger 的许可证限制和弃用通知

尽管 VRChat 宣传“Udon Node Graph 适合新手”,但很多开发者并不认同这一说法。

对新手来说,Udon Node Graph 没有简化编程,反而让简单的编程概念,如循环分支变得更复杂。当用户完成简单的开关等任务后,随着需求用户不得不需要具有编程的大部分先验知识才能在 Udon Node Graph 中用简陋的工具完成稍微复杂一点的需求,更简单的需求当新手遇到问题想在社区里获得帮助时,往往会意外的发现几乎所有资深开发者都不了解 Udon Node Graph,而这反过来又降低了 Udon Node Graph 的使用率。

// 对于 VRCSDK 2 用户,社区继承者 CyanTrigger

VRChat 社区里长出来的 UdonSharp

显然,Udon Node Graph 是无法满足开发者对于组织复杂代码、复杂工程的需求的,Udon Node Graph 也无法像常规文本脚本一样被简单复用。但好消息是,VRCSDK 并没有限制开发者自行实现新的编译器并生成 Udon VM 字节码。因此,UdonSharp (后文称 U#)这一社区项目诞生了。U# 允许用户使用 C# 的语法功能子集编写脚本,然后被 Udon VM 执行。抛开 Udon VM 的糟糕性能不谈,U# 大幅提高了开发者的开发效率,很快也被 VRChat 吸收作为官方项目。

补充资料

为什么 VRChat 不直接允许用户编写任意 Unity C# 脚本,而是将用户程序放在 Udon VM 中运行?

因为 VRChat 的每个世界都由用户创建并上传,如果允许运行任意 Unity C# 代码,可能会有人上传恶意代码破坏你的 VRChat 客户端或破坏你的电脑。因此,用户创建的代码必须通过检查以保证不包含恶意功能,或隔离在单独的运行环境让它无法影响外界。

一种可能的方案是服务器对 C# 程序集进行验证,保证不会有恶意代码,但验证用户上传的代码需要额外的服务器资源;另外尽管 Mono 和 .Net 都有沙盒功能,但该功能一直被强烈推荐不要使用。这两种做法都很容易陷入安全攻防猫鼠游戏,用户总会找到漏洞,开发者不得不像“打地鼠”一样疲于奔命修复漏洞。

因此,大多数允许用户上传代码的游戏选择的方案是嵌入沙盒化的脚本引擎。沙盒化脚本引擎可以精确地控制安全边界,只允许用户代码使用被许可的功能,就算用户代码想要破坏运行环境最多也只能破坏沙盒内的环境,无法影响沙盒宿主。VRChat 的 Udon 就是沙盒化的字节码执行引擎,只有被列入 Udon 白名单里的外部方法才能被用户的 Udon 程序调用。

将不可信代码隔离在虚拟机或沙盒中运行保证宿主安全稳定也是通用的安全策略,例如在浏览器中,网站的 JavaScript 运行在隔离沙盒,每个标签页运行在单独的进程等。