瞎折腾:用Unity撸纯HTML5移动游戏/应用

这两天灵机一动,大概折腾了个demo

(ps: 博客站的CDN在墙外(HK),如果刷不出图的话,请尝试改变一下上网方式。)

效果上有点像Unity自己家的Project Tiny那样,Build之后得到的是一个纯HTML5的前端应用。

不过不同于Tiny,我们这里设计的还是相对传统的GameObject+组件这种开发方式:场景->GameObject->组件,而非DOTS那套。

使用GameObject 挂在组件的方式编辑场景,编写C#代码,并在构建时导出HTML应用。

因为暂时没打算把它做完,就压根没往GitHub上整,大概写点东西 算是记录一下:


首先是大概思路:

这玩意其实相当于是一个独立的引擎或者说框架了,和Unity的Runtime基本上没关系。目前大体上可以分为两个部分:

一个是核心模块(core),这部分是一个独立的、与Unity无关的独立工程,由C#和TypeScript编写。在核心模块中,有一套重新实现的GameObject和Compoment的机制。核心模块可以直接用来编写业务逻辑并构建HTML应用,不需要编辑器。

直接用core部分编写业务

另一个部分就是针对Unity的扩展,把core部分的东西和Unity关联起来。

在应用构建时,Unity的扩展部分会把在编辑器中编辑的场景、Prefabs等内容读取出来,存储成Json放进HTML应用的资源中,(我们暂时在HTML应用中把Scene、Prefabs什么的都统称为Stage),然后在浏览器中运行时,Core会把各种GameObject根据JSON加载出来并挂在Components,由Core来维护整个应用的生命周期,并把需要显示的内容绘制在Canvas上。

所以,虽然说是用Unity开发HTML应用,但基本上和Unity本身没啥关系了,只是借用到了Unity的编辑器。而在应用运行时,就是个单纯的HTML应用了,就没Unity的事了(其实Tiny之前还是TypeScript的时候也是这么干的,现在不清楚,还没细看过它的实现)


也正是因为上述的原理,所以我们在实际写业务逻辑的时候,需要把我们的业务代码和Unity的内容(UnityEngine命名空间等)明确的分隔开。同理,在编辑场景的时候,我们也不能挂载Unity提供的组件(目前Unity的Canvas等几个组件除外,导出的时候会自动忽略)。

也就是说,MonoBehaviour也是不能用了。我们自己实现了一个Behaviour类,用宏定义符号做了分隔:在编辑器下,继承自MonoBehaviour,以便我们在编辑器下挂在组件和调试。而在构建HTML应用时,MonoBehaviour部分的东西就会被剥离,由Core来管理这些组件。

重新实现的Lable组件(demo阶段,所以功能贼少)

(在编辑器中调试这件事,目前的设计是用宏定义在编辑器下继承Unity的组件,比如目前的Lable在编辑器下会继承自UnityEngine.UI.Text,这样做的目前的借用Unity的Runtime来调试应用,另一方面可以直接用Unity直接的方式构建App。当然目前这个想法有没有什么坑还不知道,还没往下深入的做,没遇到坑暂时。)

浏览器里运行C#的问题:

折腾这玩意,最根本的目的是我想用C#写HTML5应用玩。所以浏览器里跑C#的问题就一定得解决了。

常见的方法有两种,一个是WebAssembly,另一个是把C#翻译成JavaScript.

权衡了各种因素,目前的实现的demo中选择了后者,我们在构建应用时把C#翻译成了JavaScript. (但其实直到现在对于两者的选择还是摇摆不定)

这里使用了开源项目Bridge.NET来实现这个功能。 把C#翻译成JavaScript在目前最大的好处是包体极小,兼容性较好,GC什么的问题也不大。

yomunsam

文章作者信息...

留下你的评论

*评论支持代码高亮<pre class="prettyprint linenums">代码</pre>

推荐ヾ(•ω•`)o