Unity向开发人员提供了多种工具,以实现具有虚拟现实特征的游戏体验。Unity的内建API以及特性可有效地实现多种可能性,并构建游戏场景和角色对象。无论开发何种游戏,理解并应用脚本特性可视为游戏设计的基本因素之一。本书将脚本技术划分为多个简单概念,进而有助于读者理解这一话题的基础内容。本书通过大量实例,详细分析所涉及的概念,并对核心概念予以实现。
《Unity脚本设计》详细阐述了与Unity脚本设计相关的基本解决方案,主要包括Unity中的C#语言,调试机制,单例模式、静态模式、GameObject以及场景世界,事件驱动程序设计,基于高级动画的Mecanim系统、相机、渲染和场景,与Mono协同工作,人工智能,与纹理、模型和2D元素协同工作,资源控制等内容。此外,本书还提供了相应的示例、代码,以帮助读者进一步理解相关方案的实现过程。
本书适合作为高等院校计算机及相关专业的教材和教学参考书,也可作为相关开发人员的自学教材和参考手册。
第1章 Unity中的C#语言
本书阐述Unity的脚本设计,因而读者需要了解Unity游戏开发环境下的C#语言。在进一步阅读之前,读者有必要明晰相关概念,进而可在理论基础上掌握脚本设计这一高级内容,此类内容多具有衔接性和实践性特征。关于衔接性,任何一种程序设计语言均会强调语法及其编程规则,这也是一种语言的正式内容之一,其中涉及变量、循环以及函数。随着程序员经验的不断增加,其关注点逐渐从语言本身转向对实际问题的处理,即由语言自身内容转向特定环境下的语言应用。因此,本书并非是一本C#语法书籍。
在结束本章的学习后,相信读者已经掌握了C#语言的基本内容,后续章节将运用C#语言处理相关案例以及实际问题,这也是本书的特点之一,并覆盖了C#语言的全部功能项,以使读者更好地理解相关操作结果。无论经验如何,这里建议读者逐章阅读,对于期望解决复杂问题的C#语言新手而言尤其如此。对于经验丰富的开发人员,本书则可强化其现有的知识,并在学习过程中提供新的建议和理念。本章将采用循序渐进的方式,从头开始阐述C#语言的基础内容。另外,如果读者熟悉另一门语言的编程知识,且尚未接触过C#语言,现在则是学习该语言的良好时机。
1.1 为何选择C#语言
当提及Unity脚本设计时,面临的一个问题则是选取哪一种语言,Unity对此提供了解决方案。相应地,官方选取方案则是C#和JavaScript语言。然而,考虑到基于Unity的特定应用,JavaScript应称作JavaScript或是UnityScript尚存争论,但其中原因并非是本书讨论的重点。当前问题是项目所选取的设计语言。作为一种方案,可在项目中选择两种语言,同时在其中分别编写脚本文件,并对这两种语言进行混合。当然,这在技术上是可行的,Unity对此并未加以限制,但这会导致混淆以及编译冲突,就像尝试同时以英里和千米为单位计算距离。
因此,这里建议采用一种语言,并在项目中作为主语言加以使用。本书则选用了C#语言,其原因在于:首先C#语言并非优于其他语言,根据个人观点,此处并不存在绝对意义上的优劣性,每种语言均包含各自的优点和应用场合;同时,所有Unity语言均可用于游戏制作。这里选择C#语言的主要因素在于其应用的广泛性,以及对Unity的支持。针对Unity,C#语言可最大限度地与开发人员现有的知识体系结构相结合。大多数Unity教程均采用C#语言编写,同时也常见于其他应用开发领域中。C#语言的历史可追溯至.NET框架,后者也可用于Unity中(称作Mono)。另外,C#语言也借鉴了C++语言的内容。在游戏开发中,C++则是一类主要的开发语言。通过学习C#程序设计语言,读者可向当今游戏界的Unity程序开发人员看齐。因此,本书选用了C#语言,进而扩大其应用范围,在现有教程以及资源的基础上,最大限度地发挥读者的知识水平。
……
第1章 Unity中的C#语言 1
1.1 为何选择C#语言 1
1.2 创建脚本文件 2
1.3 脚本的实例化操作 4
1.4 变量 6
1.5 条件语句 7
1.5.1 if语句 8
1.5.2 switch语句 10
1.6 数组 13
1.7 循环 16
1.7.1 foreach循环 16
1.7.2 for循环 17
1.7.3 while循环 18
1.7.4 无限循环 20
1.8 函数 20
1.9 事件 23
1.10 类和面向对象程序设计 24
1.11 类和继承机制 26
1.12 类和多态 28
1.13 C#属性 32
1.14 注释 34
1.15 变量的可见性 37
1.16 ?操作符 38
1.17 SendMessage和BroadcastMessage 38
1.18 本章小结 40
第2章 调试机制 41
2.1 编译错误和控制台 41
2.2 利用Debug.Log进行调制——定制消息 44
2.3 覆写ToString方法 46
2.4 可视化调试 50
2.5 错误日志 52
2.6 编辑器调试 56
2.7 使用分析工具 59
2.8 基于MonoDevelop的调试 62
2.9 Watch窗口 66
2.10 恢复执行程序和步进操作 70
2.11 调用栈 71
2.12 Immediate窗口 73
2.13 设置条件断点 74
2.14 跟踪点 76
2.15 本章小结 78
第3章 单例模式、静态模式、GameObject 以及场景世界 79
第4章 事件驱动程序设计 102
4.1 事件 102
4.2 事件管理 106
4.2.1 基于接口的事件管理 107
4.2.2 定义EventManager 109
4.3 MonoDevelop中的代码折叠——#region和#endregion 114
4.3.1 使用EventManager 115
4.3.2 基于委托机制的替代方案 116
4.3.3 MonoBehaviour事件 121
4.3.4 鼠标事件 122
4.3.5 应用程序焦点和暂停 125
4.4 本章小结 127
第5章 相机、渲染和场景 128
5.1 相机Gizmo 128
5.2 可见性 131
5.2.1 检测对象的可见性 132
5.2.2 关于对象可见性的其他问题 133
5.2.3 视锥体测试——渲染器 134
5.2.4 视锥体测试——点 135
5.2.5 视锥体测试——遮挡 136
5.2.6 相机前、后视觉 137
5.3 正交相机 138
5.4 相机渲染和后处理 142
5.5 相机震动 148
5.6 相机和动画 150
5.7 相机和曲线 152
5.8 本章小结 158
第6章 与Mono协同工作 159
6.1 表和集合 160
6.1.1 List类 160
6.1.2 Dictionary类 163
6.1.3 Stack类 164
6.2 IEnumerable和IEnumerator接口 166
6.3 字符串和正则表达式 172
6.3.1 null、空字符串和空格 172
6.3.2 字符串比较 173
6.3.3 字符串的格式化 174
6.3.4 字符串循环 175
6.3.5 创建字符串 176
6.3.6 搜索字符串 176
6.3.7 正则表达式 176
6.4 无穷参数 178
6.5 语言集成查询 178
6.6 Linq和正则表达式 181
6.7 与文本数据资源协同工作 182
6.8 从本地文件中加载文本数据 184
6.8.1 从INI文件中加载文本数据 185
6.8.2 从CVS文件中加载文本数据 187
6.8.3 从Web中加载文本数据 187
6.9 本章小结 188
第7章 人工智能 189
7.1 游戏中的人工智能 189
7.2 开始项目 191
7.3 烘焙导航网格 192
7.4 NPC主体对象 195
7.5 Mecanim中的有限状态机 198
7.6 C#语言中的有限状态机 202
7.7 构建Idle状态 204
7.8 构建Patrol状态 207
7.9 构建Chase状态 211
7.10 构建Attack状态 213
7.11 构建Seek-Health(或逃跑)状态 214
7.12 本章小结 217
第8章 定制Unity编辑器 219
第9章 与纹理、模型和2D元素协同工作 247
第10章 资源控制和其他 276