当前位置:首页 > 嵌入式培训 > 嵌入式学习 > 讲师博文 > 一瞥Unity集成开发环境中的软件工程设计思想

一瞥Unity集成开发环境中的软件工程设计思想 时间:2018-09-27      来源:未知

概述: 本文对Unity集成开发环境主要部分进行了软件工程技术上的拆解,尝试从交互式的编程技术、正向与反向工程、设计模式、组件模型设计、 面向对象的设计和软件可扩展性等几个方面进行了论述,为想深入了解Unity开发世界的技术人员奠定基础。

1 背景

Unity是一个强大的集成游戏引擎和编辑器,可以让开发者可以迅速高效地创建对象、导入外部资源,并且用代码把它们连接在一起。Unity编辑器是 可视化的,其围绕这样的原则而构建,即开发者可以使用一个简单的拖放动作来完成任何任务,甚至可以连接脚本,自己编写程序实现特定的功能。

鉴于Unity 3D的集成开发环境的安装和搭建已经有了论述,我们试图对Unity集成环境进行简要的技术解析。下面会首先介绍Unity总体集成 开发环境的主界面布局,而后对Unity的软件工具设计思想进行软件技术上的分析。

2 总体开发环境概览

正如Visual Studio为微软公司的Windows平台提供高效的开发环境一样,Unity的集成开发环境为虚拟现实(AR/VR/MR)平台的开发提供了有力的生产 力工具。下面对开发界面布局中涉及的主要子窗口略要说明。

• Scene【场景面板】:该面板为Unity3D的编辑面板;你可以将你所有的模型、灯光、 以及其他材质对象拖放到该场景中。构建游戏中所能呈现景象。

• Game【游戏面板】:与场景面板不同,该面板是用来渲染场景面板中景象的。该面 板不能用作编辑,但却可以呈现完整的动画效果。

• Hierarchy【层次清单栏】:该面板栏主要功能是显示放在场景面板中所有的物体对 象。

• Project【项目文件栏】:该面板栏主要功能是显示该项目文件中的所有资源列表。 除了模型、材质、字体等,还包括该项目的各个场景文件。

• Inspector【监视面板】:该面板栏会呈现出任何对象的所固有的属性,包括三维坐 标、旋转量、缩放大小、脚本的变量和对象等等。

• 【场景调整工具】:可改变你在编辑过程中的场景视角、物体世界坐标和本地坐标 的更换、物体法线中心的位子,以及物体在场景中的坐标位置,缩放大小等等。

• 【播放、暂停、逐帧按钮】:用于运行游戏,暂停游戏和逐帧调试程序。

• 【层级显示按钮】:勾选或取消该下拉框中对应层的名字,就能决定该层中所有物 体是否在场景面板中被显示。

• 【版面布局按钮】:调整该下拉框中的选项,即可改变编辑面板的布局。

• 【菜单栏】:和其他软件一样,包含了软件几乎所有要用到的工具下拉菜单。

图 1 Unity中文集成开发环境

图 2 Unity英文集成开发环境

由于中英文表达习惯的不同,不同的技术人员对术语的中文表达存在差异性,下面为了读者更好地理解,特此总结表格如下:

中文名称 别名列表 英文名称 游戏预览面板 Game选项卡 游戏面板 Game 场景设计面板 Scene选项卡 场景面板 Scene 游戏组成对象列表 Hierarchy选项卡 层次清单栏 Hierarchy 项目资源列表 Project选项卡 项目文件栏 Project 属性查看器 Inspector选项卡 监视面板 Inspector 菜单栏 包括各个子下拉菜单如文件/编辑/资源/游戏对象/组件/移动输入/窗口/帮助 Files/Edit/Assets/GameObject/ Component/Mobile Input/Window/Help 版面布局按钮 控制面板布局 集成环境布局 布局下拉列表 Layout(2 by 3 / 4 split…..) 屏幕显示按钮 分层操作(局部操作)/ 渲染顺序 分层下拉列表 Layers / Sorting Layers 场景调整工具 坐标轴位置调整, 物体世界坐标和本地坐标 变换Gizmo切换 Center/Pivot, Local/Global 播放、暂停、逐帧按钮 播放按钮/暂停按钮/逐帧按钮 播放控件 Play/pause/next

3 交互式编程技术

3.1 引言

计算机科学领域,交互式编程技术很早就有了实现版本,比如Tcl/Tk语言应用在美国很多高校的实验室和研究所,用来快速展现原型设计。鉴于很多 工程师刚走出校门,很多从编译型语言收益,尤其是c/c++,因此容易养成了“惯性”。随着现代编程语言的大量涌现,比如python语言,特别是网络 经济所催生的“短-平-快”模式,使得交互式的编程语言技术更加契合技术人员的生活。比如:

Python语言

Python的设计哲学是“优雅”、“明确”、“简单”,是一门完全面向对象的语言。IDLE是Python软件包自带的一个集成开发环境,初学者可以利用 它方便地创建、运行、测试和调试Python程序。IDLE带有一个编辑器,用来编辑Python程序(或者脚本);有一个交互式解释器用来解释执行Python 语句;有一个调试器来调试Python脚本。正式由于交互的解释器为该编程语言提供了便利。

Ruby语言

Ruby是一门开源的动态编程语言,注重简洁和效率。因此Ruby 的句法优雅,读起来自然,写起来舒适。它也是一种简单快捷的面向对象(面向对象程 序设计)脚本语言,它的灵感与特性来自于 Perl、Smalltalk、Eiffel、Ada以及 Lisp 语言。Ruby的交互性可以通过“irb”展现。irb是一个交互式 的Ruby界面(Ruby解释器)。可以通过irb来调试、运行和实验Ruby代码。这意味着它不用处理文件,可以直接在会话中输入代码,测试Ruby代码,同 时也是一个学习Ruby的好工具。

Powershell/Bash

Bash是Unix系统或类Unix系统支持很久的shell解释器,Powershell是微软公司新型针对Windows平台的解释器,两者都可以通过技术人员敲命令快速 实现编程。正是由于应用的普遍性,使得很多技术人员忽略了它们本身就是一门很好的,有用的和便捷的交互式编程语言。但缺点就是跟其它图形化 的解释器相比,在可视化编程方便还仍显得笨拙和低效。

总之,交互式的编程语言(很多是脚本语言)都提供类似的控制台,直接输入脚本语句,回车就执行了,结果立即显示出来,无须经过复杂的保存和 编译阶段。

3.2 Unity集成环境的场景面板

Unity 3D中,“场景”是一个视图,我们通过“场景”这个视图,来编辑、布置游戏中玩家所能见到的图像和声音。场景包含游戏的对象。它们可以 用来创建主菜单、个人级别(level)和其他任何东西。认为每个独特的场景文件作为一个独特的级别(level)。在每一个场景中,你将放置你的环 境,障碍和装饰,从而设计和构建了你的游戏。

在开发过程中,我们能在“Scene”视图中,就可以直接放入所有的游戏对象(物体),从而共同形成一个场景,而且会在Hierarchy视图中通过层级 关系列出来。

图 1 当前3个发展方向

透过上面的分析,我们能够看到Unity环境很好滴沿用了现代编程语言的交互式开发模式和体验,只需用户将需要的物体放入场景(如图中放入一个球 体),Hierarchy选项卡就可以实时看到物体的诸多属性;反过来用户修改某个属性信息又可以在场景环境中实时地看到变化。而且,在游戏(Game) 选项卡中用户能够预览到运行时的场景变化。

4 正向工程与反向工程

4.1 引言

反向工程也称逆向工程(英文是reverse engineering),是相对正向工程而言,大意是根据已有的东西和结果,通过分析来推导出具体的实现方法。 在我们现实的软件世界里,比如从某个能够做出某种动画效果的可执行程序(.exe/elf),通过反汇编、反编译和动态跟踪等技术方法,分析出其动 画效果的实现过程,这种行为就是逆向工程;不仅仅是反编译,而且还要推倒出设计,并且文档化,逆向软件工程的目的是使软件得以维护。再比如 Java代码或C#代码通过逆向构建 UML 类及序列图时,能够使得技术人员改动代码的同时实时更新建模图形的变化。技术人员往往通过IBM® Rational® Software Architect 将 Java源代码做逆向工程生成 UML 类和序列图,通过.Net / Visio软件工具将C#源代码做逆向工程诸如此类。

4.2 Unity集成环境的属性查看器

明白了上面提到的软件工程思想后,让我们瞧一瞧Unity是如何体现这一点的。

上面的图说明的是: 用户能够通过操作Unity的环境菜单生成C#脚本文件;反之,用户又可以通过修改脚本文件来改动Inspector面板的布局。比如, 正如图中显示的脚本文件中增加了Test类,在Inspector面板中有相应的更新显示。此外,如果用户对缺省的面板风格不满意,用户还能够通过在脚本 文件中继承Editor类的方法对监视面板进行大幅度的改动。我们能够看到,这里充分体现了反向工程的设计思路。

5 单实例设计模式

5.1 设计模式

按照设计模式总结的几大类软件模式设计角度,单例模式是一种对象创建模式,它用于产生一个对象的具体实例,它可以确保系统中一个类只产生一 个实例。比如说,Java 里面实现的单例是一个虚拟机的范围,因为装载类的功能是虚拟机的,所以一个虚拟机在通过自己的 ClassLoad 装载实现单 例类的时候就会创建一个类的实例。在 Java 语言中,这样的行为能带来两大好处:

1 对于频繁使用的对象,可以省略创建对象所花费的时间,这对于那些重量级对象而言,是非常可观的一笔系统开销;

2 由于 new 操作的次数减少,因而对系统内存的使用频率也会降低,这将减轻 GC (指JVM的内存回收算法)压力,缩短 GC 停顿时间。

因此对于系统的关键组件和被频繁使用的对象,使用单例模式可以有效地改善系统的性能。单例模式的核心在于通过一个接口返回唯一的对象实例。

5.2 Unity的单实例运用

在Unity的集成开发环境中,对IDE环境的配置可以通过偏好(Preferences)选项窗口进行全局性的配置,包括编辑器的选择,颜色的选择,快捷键的 设置等等,这些配置信息保存到配置文件中构建了全局唯一的配置实例。

比如外部工具选择的脚本编译器选项,在Mac系统环境下,可以选择MonoDevelop或者Xamarin Studio两种开发工具,相应地Windows系统环境下,可以 选择MonoDevelop或者Visual Studio两种IDE开发环境。这种设计思路往往在很多的可视化工具设计环境当中,我们能够找到很好的例子。另外,这里 展现的Unity环境一个不同于其它环境的特点就是考虑了设计工具的协同工作,直接和其它现成的优秀开发工具一道为项目开发更好地服务。

6 组件化设计

6.1 模块化设计

早在C语言大行其道的时代,基于模块化的设计思想受到了很大的欢迎。通过接口和实现分离的形式,在项目开发实践中得到了广泛的运用。微软公司 倡导的基于构件(Component)或组件的开发模式,构建了微软操作系统的设计哲学,尤其是.Net生态系统,从早期低效的ActiveX控件到com, 到现在 的com+,直到.Net的成熟,微软公司把组件对象模型技术发挥的淋漓尽致。

但好多技术人员还是把模块化和组件化混为一谈,两者有着共性和个性。两者理解上是否存在差异往往取决专业背景、所在领域、以及视角。 从设计上来看,组件强调复用,模块强调职责(内聚、分离),或者说组件是达到可复用要求的模块。模块或模组(Module)的核心意义是分离职责, 属于代码级模块化的产出。本身是一组具有一定内聚性代码的组合,职责明确。对外的接口可以是松散的,也可以是集中的。SEI的定义为:提供一组 连贯的职责的软件的实现单元。它以问题分解的形式,来解决软件设计问题。它更强调一个内聚的概念,形式上类似于Java语言中的包概念,也可以 是一个源代码目录(C语言也是)。

 

组件或者构件(Component)使用比较广泛,它的核心意义在于复用,相对模块,对于依赖性有更高的要求。概念上与模块基本等同,只是明显有依赖性 的要求。(早提出时概念)。

6.2 Unity的组件化应用

Unity的设计把组件化的软件工程设计思想进行了充分的发挥,Unity环境内置了打包器(Packer)和解包器(Unpacker),技术开发人员可以将自己 制作的插件打包成.unitypackage的格式,然后进行网站上的发布供其它开发人员导入。

图 10 脸谱的Oculus VR产品

比如说,Vuforia是一款由Qualcomm推出的AR应用开发工具,能将现实世界物体转变为互动体验的扩增实境平台,旨在帮助开发者打造全新级别的真实 世界物品与虚拟物品的互动。Vuforia SDK可以通过官方网站进行下载(图中的vuforia-unity-6-0-117.unitypackage名称),开发者能够在Unity的 环境下,通过下图中的菜单弹出窗口将该软件包导入项目选项卡窗口中去。与此同时,也将解压后的很多资源文件导入了项目。

7 可扩展性设计

7.1 概要思路

可扩展性设计与实现是软件工程所倡导的重要设计原则之一。若要完美地达成设计目标,需要与面向对象的设计、模块化或组件化的设计思维、设计 模式等软件设计思想结合起来进行充分的运用和发挥。面向对象设计的OCP(开-闭原则)设计原则,就是一个很好的例证。在C++类库实现的过程中, 公开的接口和封闭接口的需要针对用户的取得平衡。软件功能模块划分的“紧内聚,松耦合”,通用的部分做成平台模块,不同尽量实现成可配置模 块。还有设计模式当中的适配器模式等等,所有都很好地体现了可扩展性设计的思路。

7.2 Unity的可扩展性体现

7.2.1 Unity的Gizmos

Unity的Gizmos类可在Scene视口中绘制图像用来显示设计细节。利用Gizmos.DrawIcon函数可以在场景视口中绘制一个图标以标记特殊的对象和位置。 该函数使用的图像文件需要位于 Gizmos中。

下图中,Unity开发环境中的Gizmos按钮所涉及到的基于Gizmos类的绘制射线,线段,网格球体,实体球体,网格立方体,实体立方体,图标,GUI纹 理,以及摄像机线框。但有些特殊的场景视图,用户只能够自己编码实现定制化的Gizmos类实例。

7.2.2 Unity的编译扩展方式

再举个例子就是Unity对脚本扩展的实现方式。

通常情况下,Editor 文件夹中的脚本主要用来扩展unity编辑器的功能方便开发。这些脚本将不会打包进终发布的游戏中。项目中可以使用多个 Editor 文件夹,但是该文件夹中的脚本不允许用当GameObject对象的组件(Component)。Plugins 文件夹中存放用于扩展unity功能的插件(多为 C/C++写成的原生动态链接库(DLLs))。这些插件可以访问第三方代码库,系统API以及其他超出Unity功能的模块。

在unity开发中,有的时候定制项目文件夹以管理游戏资源,包括代码资源。但unity保留了一些特殊文件夹用来做特殊用途,例如编译顺序。

Unity的脚本编译有4个阶段(phase),脚本处在哪个编译阶段取决于脚本所在的文件夹。如果你的一些脚本需要引用一些别的文件夹中定义的类,则 需要关心他们的编译顺序。你引用的类需要先于你的当前类编译。或者当你需要引用其他语言的脚本时,那么该脚本必须处于更早的编译阶段。

Unity中的4个编译阶段如下(类似于X Windows应用对资源文件的查找方式):

1.处于 Standard Assets, Pro Standard Assets 和 Plugins 文件夹中的运行时脚本(Standard Assets 文件夹需是Assets的一 级子文件夹);

2.处于 Standard Assets, Pro Standard Assets 和 Plugins 文件夹下的以 Editor 命名的一级 子文件夹中的脚本;

3.顶级 Editor 文件夹中的脚本;

4.其他 Editor 文件夹中的脚本(例如其他文件夹下的以 Editor 命名的子文件夹) 另外在 Assets 文件夹中以 WebPlayerTemplates 命名的顶级子文件(即Assets/WebPlayerTemplates)将不会编译。若是处于别的文件夹下的 WebPlayerTemplates (如Assets/Scripts/WebPlayerTemplates)将不会防止编译。

8 面向对象的设计

8.1 面向对象设计思想

众所周知,封装、继承和多态是面向对象语言设计的三大原则。微软在早期的Visual C++版本就支持了通过类继承机制构建的庞大MFC类库,如今 的.Net类库包含了这种思想。如今流行的C++,Java,Python,Ruby等程序设计语言都支持面向对象思想的程序设计思想。

8.2 Unity的类库实现

下图Unity的类库遵照典型的类层次关系图,图中的符号含义如下:


所有类的抽象基类Object,游戏场景中所放置的所有游戏对象皆从此类继承而来,有点类似于苹果系统中的NSObject (面向对象C的基类)。Unity开发 工程中涉及用到的动画、摄像机、灯光、脚本行为、粒子渲染、碰撞器、刚体、变换、材料、网格、着色器和渲染器等等均按照类的继承和组合关系 实现的。

9 结论

本文试图带领初涉Unity开发的技术人员或工程师,站在软件工程设计和实现的角度,从多个视角挖掘和体会一下Unity集成开发环境中所蕴含的思想 ,为技术人员更好的利用该环境进行各个领域的开发打下良好的工具使用基础。

供读者参考资料:

[1] https://en.wikipedia.org/wiki/Interactive_programming

[2] //baike.baidu.com/item/Ruby/11419

[3] https://www.ruby-lang.org/zh_cn

[4] //www.ibm.com/developerworks/cn/java/j-lo-Singleton/index.html

上一篇:Linux字符设备驱动模型之设备号

下一篇:简析静态库与动态库

热点文章推荐
华清学员就业榜单
高薪学员经验分享
热点新闻推荐
前台专线:010-82525158 企业培训洽谈专线:010-82525379 院校合作洽谈专线:010-82525379 Copyright © 2004-2022 北京华清远见科技集团有限公司 版权所有 ,京ICP备16055225号-5京公海网安备11010802025203号

回到顶部