解构统一的腳本物件模型

  

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

  

解构统一的腳本物件模型”> <br/>从这个类图我们可以理解它的结构,及如何把一些常用功能映射至这系统里,以下分节讨论。</p>
  <br/> <p> GameObject和组件统一的执行环境里,会有一个场境(场景)。这个场境包含一个GameObject对象的层阶(层次)。这个GameObject类只是一个容器,本身没有其他功能。使用者需要为GameObject加入各种组件对象来定义它的行为,而不是透过继承(继承)GameObject来加入行为。一个对象可拥有多个组件对象,但有一些组件类别只可以在一个GameObject中有一个实例(实例)。</p>
  <p> MonoBehavior <br/>我最感兴趣的,是使用者如何自行定义行为来做出不同的游戏。在统一中,程式员编写的脚本,其实也是组件的一种,所有的脚本都会继承自MonoBehavior类别。以下是一个简单例子:</p>
  <p>的var速度=5.0;</p>
  <p>函数Update () {<br/> var x=Input.GetAxis (“Horizontal") <em> Time.deltaTime </em>速度;<br/> var z=Input.GetAxis (“Vertical") <em> Time.deltaTime </em>速度;<br/>变换。翻译(x, 0, z); <br/>} </p>
  <p>把这个脚本加进一个GameObject的话(成为该GameObject的一个组件),运行会在每帧呼叫更新(),玩家就可以用上下左右键控制那个GameObject在水平方向移动. . </p>
  <p>变换<br/>每个能在三维空间里的GameObject都会有变换组件(未有详细看是否有一些GameObject可以省郤变换,例如一个用来定义一个游戏任务的GameObject) .Transform包括平移,旋转及缩放。之前的例子已用了变换组件,不过它其实是对象类别的一个简写,这简写其实等同:</p>
  <p> GetComponent(变换)。翻译(x 0 z) <br/>组件的连结</p>
  <p>在脚本教程里的例子是写一个遵循的行为,拥有这个组件的GameObject会自动追踪(面对着)一个目标对象:</p>
  <p> var目标:变换;</p>
  <p>函数Update () {<br/> transform.LookAt(目标),<br/>} </p>
  <p>这个脚本暴露了一个目标变量(应当作成员变量吧),使用者可以把其他对象的变分配至这个变量。这任务有两种方法实现,其一是利用统一的GUI工具把一个组件实例的变量(如变换)拖放至这个组件实例的目标变量,而另一个方法是写代码:</p>
  <p> var newTarget=GameObject.Find (“Cube") .transform; <br/> GetComponent(跟随)。目标=newTarget; </p>
  <p>用代码就可以这样动态改变这些组件之间的联结方式,或者另一个说法是,GUI工具是可以设定起始的联结,而脚本可以在执行期改变这些联结。</p>
  <p>渲染<br/>一个可被渲染的GameObject需要有以几个组件,以网格为例:</p>
  <p> MeshFilter:用来找出现时的网格对象<br/> MeshRenderer:用来渲染网的组件,会参考一个材料对象<br/>要注要网格和材料对象并非组件,它们是继承自对象的。你可以动态改变它们。但由于它们不是组件,所以可以被分享,例如多个GameObject的MeshRenderer都参考到同一个材料。一个组件实例只属于一个GameObject(所以在UML中我用黑色钻石表示成分)。而光线和相机则是组件,这意未着可以简单的设定联结。</p>
  <p>分析<br/>统一的脚本对象模型是以组件为基础的。透过把组件实例加入GameObject实例来组合不同功能的对象,而组件实例之间可以建立联结。这种方式不需要透过继承(继承),而是透过聚合(聚合)加入对象的功能和行为。使用聚合的好处是不会产生复杂的继承层阶,亦可以动态改变聚合的结构(例如在执行期加入或移除组件)。有一些细节我暂时未清楚,例如多个组件在一个GameObject中的执行次序如何设定;联结会否有cylic的问题等等。可能要拿到软件再试用才可以知道。</p>
  <p>结语<br/>统一的脚本系统给我的感觉是使用非常简单。透过很少的代码就能写一些行为,甚至把行为组合到对象中。但是,通常容易的东西都会有相对的缺点,例如在效能上或是可伸缩性上。后者可能是一个很大的问题,当游戏规模扩大,组件和联结就会变成一个很复杂的图,由于连结是发生于执行期(而非静态),可能要作改动会变得困难。换句话说,就是改几十个类别容易,改它们的几千个实例就会很困难。软件设计世界里当然没有银×××,每个方案都适合不同的情况。我认为统一的一个设计目标是容易使用,就是像Virtools之流,可以给没有程式底子的人做游戏,相对来说做比较复杂的项目可能会遇到许多问题。但参考一下总可以给予对事物新的观点,或分析另一个科案的优越之处。<h2 class=解构统一的腳本物件模型