木匣子

Web/Game/Programming/Life etc.

Unity3d 的 GUI 框架分析

本系列的第三篇,以 Unity3d 为例,看看其如何实现基于事件的 GUI 框架。

本文分析的是 uGUI,而非 Unity3d 的 Editor UI 。后者是一种称为立即模式(Immediate Mode)的 UI 交互方式,Unity3d 的编辑器插件以及非常早期的 Unity UI 使用这种方式开发。

与 Cocos2d 或者 Egret 不同的是,Unity3d 是一个基于组件-实体-系统(Entity-Component-System[1][2])框架的游戏引擎。虽然是商业引擎,但 Unity3d 将 UI 的大部分代码托管于 Bitbucket ,详见这里。里面除了最具价值的 RectTransform 和 Canvas 之外,都开源了。花了一些时间将其中比较核心的类图画出来,被它的复杂度震惊了:

unity3d-cls-1

Unity3d 的 UI 框架非常的复杂,由于是基于 ECS 框架,代码非常零散。此外 Unity3d 允许将 GUI 渲染在屏幕甚至是 3D 表面,并且对实体的碰撞检测(hitTest)甚至可以是基于物理的。这需求远超出我的想像,所以它的抽象性非常高。

Egret 的 GUI 框架分析

本系列的第二篇,以 egret 为例,看看其如何实现基于事件的 GUI 框架。

Egret 是另一款基于 html5 的国产开源游戏引擎。其框架结构大量参考 Flash ,并且使用 TypeScript 这种强类型脚本语言,特别适合早期的 ActionScript 3.0 游戏开发者迁移到 Egret 的开发环境。

虽然我并没有用它做过比较大的项目,但是对它的实现也是保持了一点的好奇心。同第一篇一样,我将 egret 框架中与 GUI 有关的类绘制出来,方便理解:

egret-cls-1

通过与上一篇的 Cocos2d-html5 对比,我们可以看到以下概念在 Egret 里有何区别。

Cocos2d-html5 的 GUI 框架分析

本系列的第一篇,以 cocos2d-html5 为例,分析其如何实现基于事件的 GUI 框架。

Cocos2d-x 是当下非常流行的跨平台游戏引擎,其衍生版 Cocos2d-html5 是使用 Javascript 编写并运行于浏览器的 Canvas 的版本,非常符合我的口味。源码可以在这里下载。

经过简单梳理,我将源码中与 GUI 相关的几个类以及主要函数提取并绘制成类图,方便理解:

cocos2d-html5-cls-1

从这张图里可以总结出一些有趣的概念:

浅析事件驱动的 GUI 原理

从中学时期做 Flash 开发,到大学期间学 App 开发,到毕业后当了几年手机游戏开发者,再到现在转行做 Web 前端。在脑海里一直挥洒不去的疑问就是「如何从 0 开始实现一个 GUI 框架」。

期间间断性地尝试过找一些书看,但大部分都是教如何用现成的桌面 GUI 框架(例如 Java Swing,Qt,WPF 等)写一些软件或者 APP 。而非我想要的那种偏实践性的,从概念介绍 GUI 架构并一步一步实现的文献。

不过在经过使用那么多框架后做了各种各样的项目后,其实已经从这些框架中汲取了不少思想。所以想通过对几个游戏引擎的分析,来看看交互程序中的 GUI 是如何工作的。如果有时间,或许可以试着在网页的 Canvas 上实现一个简单的 GUI 框架。

为什么选游戏引擎?因为游戏引擎是非常典型的图形交互程序,而且游戏引擎的 GUI 部分相对于传统应用程序而言更加精炼,容易理解。经过考查,我选了三个游戏引擎,分别是 cocos2d-html5egret-coreunity3d-ui

写在 26 岁末

2015

去年的这个时候,我从厦门勇仕网络离职,准备了一个月雅思。虽然首战口语成绩不理想,但刚过完 26 岁的生日后就迫不及待乘上了厦门直飞墨尔本的航班,与远在他乡的 LP 团聚。

在飞机上的 10 个小时真是无比漫长,晚上飞机的轰鸣声,以及狭小的空间让人难以入睡。不过想着马上能见到亲爱的 LP ,这点小折磨根本算不上什么。

听 LP 描述的墨村,是个很荒凉的地方,半夜出门是看不到活物的,也没有可以吃宵夜的小店。当飞机抵达墨尔本上空的时候是上午,我正好坐在窗边,往下望去,没有看到什么高楼大厦,只见一小撮有点繁华的村中城,也就是 CBD 。

飞机顺利着陆,入关取行李花了一个多小时。LP 已经早早在机场门口等候。随后一起打车回到了不久前她新搬的家,一个离 CBD 非常近的地方。

iPhone 失而复得记

周六和朋友出去玩,回来走在路上还聊得很嗨。晚上回家歇了一个小时才发现 iPhone 不在口袋里。不紧不慢的让 LP 给我手机打个电话,看看房间里有没有声响。结果半天没有动静,这才想到会不会是丢了。两个小时前还在甜品店玩 Royale Clash Clash Royale[1],然后去了趟人满为患的华超。不至于招贼了吧!

博客迁移记录

木匣子 2010

记得是大一暑假的时候,我去了厦门网宿科技研发部的流媒体实验室,做 Flash 流媒体播放器的开发实习。赚了点零花钱,于是在 gegehost 买了 mutoo.im[1] 这个域名,以及一个 100 元/年的新手型主机,机房位于美国[2]。真是物美价廉,它是一个基于 cPanel 管理的 LAMP 共享主机,麻雀虽小五脏俱全。然后架了个 Wordpress 开始码字,记录大学期间的一些学习笔记。

木匣子 2013

毕业后,在厦门四三九九做 Cocos2d-js 手机游戏开发。工作之余发现 Typecho 这个简单美的 PHP 博客引擎,并且还支持 Markdown[3] 。比起 Wordpress 这样的庞然大物,我觉得 Typecho 更适合我这样的码农。于是就把 Wordpress 压箱底了。

虽然 Typecho 提供了迁移工具,可以导入 Wordpress 的文章。但是我不喜欢把新旧的东西混在一起,更喜欢让它们保持原来的样子,所以就将原来的 Wordpress 博客放到另外的二级域名了。

Wordpress 一直是博客界的明星,不过也有很多不错的后起之秀。Typecho 就是其中之一。但是 Typecho 的社区活跃度一直很低,版本更新停滞不前[4]。在后来的工作生活中,慢慢喜欢上 Javascript,并且注意到 Nodejs 社区有越来越多优秀的开源软件。其中 ghost 可以算是博客引擎中的一匹黑马。而相对于 PHP,我更愿意把时间花在研究 Javascript 上,所以一直想要试试这款新的博客引擎。

但是用了这么多年的 LAMP 主机并不提供 Nodejs 环境,所以没办法搭建 Ghost 博客,这件事就也搁置下来。

木匣子 2017

有一年半没有写博客,在这期间发生了很多事。从游戏公司辞职,然后考雅思出国,再到澳洲改行做前端。生活好不容易稳定下来,于是又有时间静下来整理思绪。

七月底收到主机续费的邮件,想着不如在 AWS 上搞个虚拟主机,把博客搬过去。即可以自己当运维,顺便学一下 DevOp 相关的知识,又可以把 Ghost 搞起来。现在终于如愿以偿。之后会整理一篇踩坑日志,敬请期待。


  1. mutoo.im 作 namespace 的时候,域名转置为 im.mutoo 即 I’m mutoo. ↩︎

  2. 域名不需要备案,同时可作 http proxy 在敏感时期获取一些资讯。 ↩︎

  3. Markdown 101 ↩︎

  4. 截止到本文发布,Typecho 在 github 上获得 3,397 个 stars ,而 Ghost 则有 23,300 个 stars 。 ↩︎

Hello Ghost.

最近把博客搬到了 AWS 上。折腾了好久,终于换上了期待已久的 Ghost 博客引擎:

Ghost is a fully open source, hackable platform for building and running a modern online publication.

这是一个基于 Nodejs 的博客引擎,完全由 Javascript 驱动。这也是为什么我这么喜欢的原因。

为了保证原来博客的访问性,早期的博客被自动 301 永久重定向到 木匣子2013 以及 木匣子2010 。将来如果还换系统的话,估计会把这个博客重定向到 木匣子2017 吧。

一年半没有写博客了,这一年来发生了很多事。将会在今后的博客中慢慢回味,敬请期待。