一起谈.NET技术,解构Unity的腳本物件模型

简介: Unity 是一个以 Mono 为基础的游戏开发环境,能同时支持三种脚本语言,包括 C#、Javascript 和 Boo (类似 Python)。由于 Unity 的开发工具暂时只有 Mac 的版本 (2010年2月25日更新: 现时已有Windows版本,而且有免费授权版,另外因为Unity iPhone版的出现使Unity的使用者大增),所以暂时未能测试。

Unity 是一个以 Mono 为基础的游戏开发环境,能同时支持三种脚本语言,包括 C#、Javascript 和 Boo (类似 Python)。 由于 Unity 的开发工具暂时只有 Mac 的版本 (2010年2月25日更新: 现时已有Windows版本,而且有免费授权版,另外因为Unity iPhone版的出现使Unity的使用者大增),所以暂时未能测试。但是它有很详细的文档,看上来很易用,所以就从文字上学习它的 Script 使用方式。 跟据一些 Tutorial参考手册,我用 Graphviz 画了一个 (我认为) 最核心的 UML 类图:

从这个类图我们可以理解它的结构,及如何把一些常用功能映射至这系统里,以下分节讨论。

GameObject 和 Component

Unity 的执行环境里,会有一个场境 (Scene)。这个场境包含一个 GameObject 对象的层阶 (Hierarchy)。 这个 GameObject 类只是一个容器,本身没有其他功能。使用者需要为 GameObject 加入各种 Component 对象来定义它的行为,而不是透过继承 (inherit) GameObject 来加入 行为。 一个对象可拥有多个 Component 对象,但有一些 Component 类别只可以在一个 GameObject 中有一个 实例 (instance)。

MonoBehavior

我最感兴趣的,是使用者如何自行定义行为来做出不同的 Gameplay。在 Unity 中,程式员编写的 Script,其实也是 Component 的一种,所有的 Script 都会继承自 MonoBehavior 类别。以下是一个简单例子:

var speed = 5.0;
function Update () {
    var x = Input.GetAxis("Horizontal") * Time.deltaTime * speed;
    var z = Input.GetAxis("Vertical") * Time.deltaTime * speed;
    transform.Translate(x, 0, z);
}

把这个 Script 加进一个 GameObject 的话 (成为该 GameObject 的一个 Component),Runtime 会在每帧呼叫 Update(),玩家就可以用上下左右键控制那个 GameObject 在水平方向移动。。

Transform

每个能在三维空间里的 GameObject 都会有 Transform Component (未有详细看是否有一些 GameObject 可以省郤 Transform,例如一个用来定义一个游戏任务的 GameObject)。Transform 包括平移、旋转及缩放。 之前的例子已用了 Transform Component,不过它其实是 Object 类别的一个简写,这简写其实等同:

GetComponent(Transform).Translate(x, 0, z)

Component 的连结

在 Script Tutorial 里的例子是写一个 Follow 的行为,拥有这个 Component 的 GameObject 会自动追踪 (面对着) 一个目标对象:

var target : Transform;
function Update () {
    transform.LookAt(target);
}

这个 Script 暴露了一个 target 变量 (应当作成员变量吧),使用者可以把其他对象的变 assign 至这个变量。这 assignment 有两种方法实现,其一是利用 Unity 的 GUI 工具把一个 Component 实例的变量 (如Transform) drag-and-drop 至这个 Component 实例的 target 变量,而另一个方法是写代码:

var newTarget = GameObject.Find("Cube").transform;
GetComponent(Follow).target = newTarget;

用代码就可以这样动态改变这些 Component 之间的联结方式。或者另一个说法是,GUI 工具是可以设定起始的联结,而 Script 可以在执行期改变这些联结。

渲染

一个可被渲染的 GameObject 需要有以几个 Components,以 Mesh 为例:

  1. MeshFilter: 用来找出现时的 Mesh 对象
  2. MeshRenderer: 用来渲染 Mesh 的 Component,会参考一个 Material 对象

要注要 Mesh 和 Material 对象并非 Component,它们是继承自 Object 的。你可以动态改变它们。但由于它们不是 Component ,所以可以被分享,例如多个 GameObject 的 MeshRenderer 都参考到同一个 Material。一个 Component 实例只属于一个 GameObject (所以在 UML 中我用黑色钻石表示 Composition)。 而 Light 和 Camera 则是 Component,这意未着可以简单的设定联结。

分析

Unity 的 Script 对象模型是以 Component 为基础的。透过把 Component 实例加入 GameObject 实例来组合不同功能的对象,而 Component 实例之间可以建立联结。 这种方式不需要透过继承 (inheritance),而是透过聚合 (aggregation)加入对象的功能和行为。使用聚合的好处是不会产生复杂的继承层阶,亦可以动态改变聚合的结构 (例如在执行期加入或移除 Component)。 有一些细节我暂时未清楚,例如多个 Component 在一个 GameObject 中的执行次序如何设定;联结会否有 cylic 的问题等等。可能要拿到软件再试用才可以知道。

结语

Unity 的脚本系统给我的感觉是使用非常简单。透过很少的代码就能写一些行为,甚至把行为组合到对象中。但是,通常容易的东西都会有相对的缺点,例如在效能上或是 Scalability 上。后者可能是一个很大的问题,当游戏规模扩大,Component 和联结就会变成一个很复杂的 graph,由于连结是发生于执行期 (而非静态),可能要作改动会变得困难。换句话说,就是改几十个类别容易,改它们的几千个 实例就会很困难。 软件设计世界里当然没有银子弹,每个方案都适合不同的情况。我认为 Unity 的一个设计目标是容易使用,就是像 Virtools 之流,可以给没有程式底子的人做游戏,相对来说做比较复杂的项目可能会遇到许多问题。但参考一下总可以给予对事物新的观点,或分析另一个科案的优越之处。

之后还有一篇关于 CryEngine 的脚本分析,但现时我在家里开发的 Mil 引擎主要是采用 Unity 的物件模型。

本文原来是繁体中文,在2008-02-29发表于http://miloyip.seezone.net/?p=15,本文經過修正。

目录
相关文章
|
3月前
|
监控 Cloud Native 测试技术
.NET技术深度解析:现代企业级开发指南
每日激励:“不要一直责怪过去的自己,他曾经站在雾里也很迷茫”。我是蒋星熠Jaxonic,一名在代码宇宙中探索的极客旅人。从.NET Framework到.NET 8,我深耕跨平台、高性能、云原生开发,践行领域驱动设计与微服务架构,用代码书写技术诗篇。分享架构演进、性能优化与AI融合前沿,助力开发者在二进制星河中逐光前行。关注我,共探技术无限可能!
.NET技术深度解析:现代企业级开发指南
|
3月前
|
人机交互 开发工具 vr&ar
使用Unity引擎开发Rokid主机应用的模型交互操作
本文介绍如何使用Unity引擎结合Rokid OpenXR Plugin开发空间计算应用,实现射线交互、模型操作等功能。涵盖环境配置、Demo导入、UI搭建与脚本编写,助力开发者快速构建AR交互应用。
|
11月前
|
算法 测试技术 vr&ar
Unity Vufoia+AR模型抖动的问题
**图像识别与跟踪精度问题**:Vuforia 依赖特征点检测,环境光线不稳定、目标纹理不丰富或遮挡会导致特征点匹配误差,引起AR模型抖动。跟踪丢失和重定位延迟也会导致模型不稳定。 **设备硬件与性能问题**:移动设备摄像头易受手持抖动影响,低性能设备无法及时处理图像数据,导致跟踪结果更新延迟。 **模型与坐标系问题**:AR模型重心设置不合理或坐标系转换误差,会使模型在虚拟空间中不稳定。 **算法与参数设置问题**:跟踪算法局限性和参数设置不合理(如灵敏度过高或平滑度过低)都会影响跟踪稳定性。 。
|
11月前
|
人工智能 自动驾驶 数据可视化
D1net阅闻 | ChatGPT支持所有用户使用搜索功能之时,谷歌也开放了最强模型
D1net阅闻 | ChatGPT支持所有用户使用搜索功能之时,谷歌也开放了最强模型
|
11月前
|
人工智能 搜索推荐 机器人
D1net阅闻|据悉微软致力于在365 Copilot产品中添加非OpenAI模型
D1net阅闻|据悉微软致力于在365 Copilot产品中添加非OpenAI模型
|
9月前
|
SQL 小程序 API
如何运用C#.NET技术快速开发一套掌上医院系统?
本方案基于C#.NET技术快速构建掌上医院系统,结合模块化开发理念与医院信息化需求。核心功能涵盖用户端的预约挂号、在线问诊、报告查询等,以及管理端的排班管理和数据统计。采用.NET Core Web API与uni-app实现前后端分离,支持跨平台小程序开发。数据库选用SQL Server 2012,并通过读写分离与索引优化提升性能。部署方案包括Windows Server与负载均衡设计,确保高可用性。同时针对API差异、数据库老化及高并发等问题制定应对措施,保障系统稳定运行。推荐使用Postman、Redgate等工具辅助开发,提升效率与质量。
378 0
|
11月前
|
图形学 开发者
Unity编辑器脚本(添加/删除)碰撞盒
这段代码提供了两个Unity编辑器工具,用于批量处理模型的碰撞盒。一是“一键添加所有碰撞盒”,通过选择模型的父物体,自动为其子物体添加`MeshCollider`。二是“一键清理所有Collider碰撞盒”,同样选择父物体后,递归删除子物体上的`BoxCollider`组件。两者均通过Unity的菜单项实现便捷操作,方便开发者快速调整场景中的物理属性。
|
11月前
|
人工智能 机器人 量子技术
D1net阅闻 | 李飞飞团队训练出媲美DeepSeek R1的推理模型 云计算费用不到50美元
D1net阅闻 | 李飞飞团队训练出媲美DeepSeek R1的推理模型 云计算费用不到50美元
|
11月前
|
人工智能 5G 数据库
D1net阅闻|谷歌被曝正使用Anthropic的Claude模型来改进其Gemini AI
D1net阅闻|谷歌被曝正使用Anthropic的Claude模型来改进其Gemini AI
|
开发框架 算法 .NET
C#/.NET/.NET Core技术前沿周刊 | 第 15 期(2024年11.25-11.30)
C#/.NET/.NET Core技术前沿周刊 | 第 15 期(2024年11.25-11.30)
221 6