游戏设计:原型与开发 18:Unity入门的第一课

游戏设计:原型与开发 18:Unity入门的第一课

一、1GB 的下载,和一个有点浪漫的选择

这一章开始,作者终于不再讲思维体操了------要装软件了。

第一句话很实在:Unity 安装包 1GB 以上,网速快几分钟,网速慢几小时。写完这段话的时候,主版本还是 Unity 4,版本号大概是 4.x.y 那种"永远在更新"的形态。

然后是那句藏在提示框里的细节:Unity 免费,但需要许可;第一次运行必须联网激活。这大概是很多新手的第一个"卡住的地方"------不是不会写代码,是没网。

Unity 不是一个软件,是一个"组装车间"

作者对 Unity 的定位非常准确:它本身是一个组装程序。素材大多在别处生产:
#mermaid-svg-j1TKswiffKn98Od5{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-j1TKswiffKn98Od5 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-j1TKswiffKn98Od5 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-j1TKswiffKn98Od5 .error-icon{fill:#552222;}#mermaid-svg-j1TKswiffKn98Od5 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-j1TKswiffKn98Od5 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-j1TKswiffKn98Od5 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-j1TKswiffKn98Od5 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-j1TKswiffKn98Od5 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-j1TKswiffKn98Od5 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-j1TKswiffKn98Od5 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-j1TKswiffKn98Od5 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-j1TKswiffKn98Od5 .marker.cross{stroke:#333333;}#mermaid-svg-j1TKswiffKn98Od5 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-j1TKswiffKn98Od5 p{margin:0;}#mermaid-svg-j1TKswiffKn98Od5 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-j1TKswiffKn98Od5 .cluster-label text{fill:#333;}#mermaid-svg-j1TKswiffKn98Od5 .cluster-label span{color:#333;}#mermaid-svg-j1TKswiffKn98Od5 .cluster-label span p{background-color:transparent;}#mermaid-svg-j1TKswiffKn98Od5 .label text,#mermaid-svg-j1TKswiffKn98Od5 span{fill:#333;color:#333;}#mermaid-svg-j1TKswiffKn98Od5 .node rect,#mermaid-svg-j1TKswiffKn98Od5 .node circle,#mermaid-svg-j1TKswiffKn98Od5 .node ellipse,#mermaid-svg-j1TKswiffKn98Od5 .node polygon,#mermaid-svg-j1TKswiffKn98Od5 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-j1TKswiffKn98Od5 .rough-node .label text,#mermaid-svg-j1TKswiffKn98Od5 .node .label text,#mermaid-svg-j1TKswiffKn98Od5 .image-shape .label,#mermaid-svg-j1TKswiffKn98Od5 .icon-shape .label{text-anchor:middle;}#mermaid-svg-j1TKswiffKn98Od5 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-j1TKswiffKn98Od5 .rough-node .label,#mermaid-svg-j1TKswiffKn98Od5 .node .label,#mermaid-svg-j1TKswiffKn98Od5 .image-shape .label,#mermaid-svg-j1TKswiffKn98Od5 .icon-shape .label{text-align:center;}#mermaid-svg-j1TKswiffKn98Od5 .node.clickable{cursor:pointer;}#mermaid-svg-j1TKswiffKn98Od5 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-j1TKswiffKn98Od5 .arrowheadPath{fill:#333333;}#mermaid-svg-j1TKswiffKn98Od5 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-j1TKswiffKn98Od5 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-j1TKswiffKn98Od5 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-j1TKswiffKn98Od5 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-j1TKswiffKn98Od5 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-j1TKswiffKn98Od5 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-j1TKswiffKn98Od5 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-j1TKswiffKn98Od5 .cluster text{fill:#333;}#mermaid-svg-j1TKswiffKn98Od5 .cluster span{color:#333;}#mermaid-svg-j1TKswiffKn98Od5 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-j1TKswiffKn98Od5 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-j1TKswiffKn98Od5 rect.text{fill:none;stroke-width:0;}#mermaid-svg-j1TKswiffKn98Od5 .icon-shape,#mermaid-svg-j1TKswiffKn98Od5 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-j1TKswiffKn98Od5 .icon-shape p,#mermaid-svg-j1TKswiffKn98Od5 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-j1TKswiffKn98Od5 .icon-shape .label rect,#mermaid-svg-j1TKswiffKn98Od5 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-j1TKswiffKn98Od5 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-j1TKswiffKn98Od5 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-j1TKswiffKn98Od5 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} MonoDevelop / IDE

写 C# 代码
Unity

组装 · 布局 · 编译
MAYA · 3ds Max · Blender

建模型与材质
Photoshop · GIMP

做贴图与 UI
Pro Tools · Audacity

剪音频
Windows
macOS
Web
iOS / Android
更多平台

图说 :这张图解释了 Unity 的"中心化"角色------它不生产内容,它编排内容。左边四个方框代表你的工作流外围,右边五个方框代表同一份工程能导出的平台。理解这一点,你才不会指望在 Unity 里"画"出一个角色------那是建模软件的事。


二、为什么选 Unity?四个理由,其中一个很可爱

作者列了四条,我按"可信度"重排一下:

① 免费。 免费版就能开发兼容 OSX、Windows、Web、Linux、iOS、Android、BlackBerry、Windows Phone、Windows Store 的游戏。专业版 1500 美元(或 75 美元/月),而学生一年的教育许可大约只要 150 美元------打 1 折。注意:教育许可不允许直接发售作品,想卖钱还得升级商业版。

② 一次编写,到处部署。 同一套源码、同一套源文件,导出多个平台。作者特意点明:这正是"Unity"这个名字的由来。

③ 社区。 几十万开发者在用,论坛很热。

④ "它非常出色!" ------ 作者和学生的玩笑是:Unity 有一个"变出色(make it awesome)按钮"。严格来说不存在,但很多功能确实只是勾一个复选框,画面立刻好看。因为 Unity 已经替你解决了一堆硬骨头:

Unity 内置解决的难题 如果你自己写,要花多久
碰撞检测 数学 + 空间划分,够写一章
物理模拟 够写一本书
寻路(Pathfinding) 够写一篇论文
粒子系统 够写一个学期
绘制调用批处理(Batching) 够调一周性能
着色器 够学一门新语言
游戏主循环 这是"引擎"的本体

这张表的潜台词是:别把时间花在已经有答案的问题上。你的时间应该花在"这个游戏为什么好玩"上。


三、为什么是 C#?一场关于"弱类型"的吐槽

Unity 支持三种语言:UnityScript(JavaScript 变体)、C#、Boo。作者说得很直白:几乎没人真的用 Boo,所以基本是二选一。

他对 JavaScript 的批评很有画面感:弱类型意味着你可以建一个叫 bob 的变量,然后往里塞数字、单词、整本小说、甚至游戏主角。于是"Unity 永远也不知道 bob 到底代表什么"。这种自由让脚本变得乏味,也让你用不上现代语言的强大特性。

C# 则是 2000 年微软为对抗 Java 而做的:把 Java 的现代特性揉进 C++ 程序员熟悉的语法里。老手能得到委托、动态绑定、运算符重载、lambda、LINQ;新手只需要知道一件事------用 C# 入门,会把你养成更合格的程序员。

这不是空口白话。作者在南加大教书时做过对照:学 C# 的学生,做出的原型水平更高、编码习惯更强、对自己的能力也更自信。

维度 UnityScript C#
类型系统 弱类型,变量随时变脸 强类型,编译期就拦住你
上手速度 快 稍慢
长期收益 容易写出"能跑但说不清"的代码 习惯、结构、可维护性
作者课堂结论 原型水平较低 原型水平更高、更自信

一个必须澄清的迷思:三种语言跑得一样快

有经验的程序员可能会想:C# 是编译型,JS 是解释型,那 C# 应该更快吧?

作者的答案是:在 Unity 里,一样快 。因为不管你保存哪种脚本,Unity 都会先把它转成通用中间语言 CIL,再把 CIL 编译成机器码。
#mermaid-svg-TEm7zC6KTp02AQCL{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-TEm7zC6KTp02AQCL .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-TEm7zC6KTp02AQCL .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-TEm7zC6KTp02AQCL .error-icon{fill:#552222;}#mermaid-svg-TEm7zC6KTp02AQCL .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-TEm7zC6KTp02AQCL .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-TEm7zC6KTp02AQCL .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-TEm7zC6KTp02AQCL .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-TEm7zC6KTp02AQCL .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-TEm7zC6KTp02AQCL .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-TEm7zC6KTp02AQCL .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-TEm7zC6KTp02AQCL .marker{fill:#333333;stroke:#333333;}#mermaid-svg-TEm7zC6KTp02AQCL .marker.cross{stroke:#333333;}#mermaid-svg-TEm7zC6KTp02AQCL svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-TEm7zC6KTp02AQCL p{margin:0;}#mermaid-svg-TEm7zC6KTp02AQCL .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-TEm7zC6KTp02AQCL .cluster-label text{fill:#333;}#mermaid-svg-TEm7zC6KTp02AQCL .cluster-label span{color:#333;}#mermaid-svg-TEm7zC6KTp02AQCL .cluster-label span p{background-color:transparent;}#mermaid-svg-TEm7zC6KTp02AQCL .label text,#mermaid-svg-TEm7zC6KTp02AQCL span{fill:#333;color:#333;}#mermaid-svg-TEm7zC6KTp02AQCL .node rect,#mermaid-svg-TEm7zC6KTp02AQCL .node circle,#mermaid-svg-TEm7zC6KTp02AQCL .node ellipse,#mermaid-svg-TEm7zC6KTp02AQCL .node polygon,#mermaid-svg-TEm7zC6KTp02AQCL .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-TEm7zC6KTp02AQCL .rough-node .label text,#mermaid-svg-TEm7zC6KTp02AQCL .node .label text,#mermaid-svg-TEm7zC6KTp02AQCL .image-shape .label,#mermaid-svg-TEm7zC6KTp02AQCL .icon-shape .label{text-anchor:middle;}#mermaid-svg-TEm7zC6KTp02AQCL .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-TEm7zC6KTp02AQCL .rough-node .label,#mermaid-svg-TEm7zC6KTp02AQCL .node .label,#mermaid-svg-TEm7zC6KTp02AQCL .image-shape .label,#mermaid-svg-TEm7zC6KTp02AQCL .icon-shape .label{text-align:center;}#mermaid-svg-TEm7zC6KTp02AQCL .node.clickable{cursor:pointer;}#mermaid-svg-TEm7zC6KTp02AQCL .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-TEm7zC6KTp02AQCL .arrowheadPath{fill:#333333;}#mermaid-svg-TEm7zC6KTp02AQCL .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-TEm7zC6KTp02AQCL .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-TEm7zC6KTp02AQCL .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-TEm7zC6KTp02AQCL .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-TEm7zC6KTp02AQCL .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-TEm7zC6KTp02AQCL .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-TEm7zC6KTp02AQCL .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-TEm7zC6KTp02AQCL .cluster text{fill:#333;}#mermaid-svg-TEm7zC6KTp02AQCL .cluster span{color:#333;}#mermaid-svg-TEm7zC6KTp02AQCL div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-TEm7zC6KTp02AQCL .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-TEm7zC6KTp02AQCL rect.text{fill:none;stroke-width:0;}#mermaid-svg-TEm7zC6KTp02AQCL .icon-shape,#mermaid-svg-TEm7zC6KTp02AQCL .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-TEm7zC6KTp02AQCL .icon-shape p,#mermaid-svg-TEm7zC6KTp02AQCL .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-TEm7zC6KTp02AQCL .icon-shape .label rect,#mermaid-svg-TEm7zC6KTp02AQCL .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-TEm7zC6KTp02AQCL .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-TEm7zC6KTp02AQCL .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-TEm7zC6KTp02AQCL :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} C# 脚本
CIL

通用中间语言
UnityScript / Boo
机器码
运行时

图说 :三条输入箭头最终汇进同一个 CIL 节点,这就是"速度一样"的原因------它们根本不是直接跑的。理解这张图还有个额外好处:以后看到"某语言更快"的营销话术,你会先问一句"它编译到哪一层"。


四、作者的教学法:三步,其中一步是"故意坑你"

掌握新语言不容易。作者打了个很妙的比方:学到某个阶段,你会像"学了一学期西班牙语就去看西语肥皂剧"------每个词都认识,整句话不知所云。他所有的学生半个学期后都有这种感觉,但学期结束时都会变得自信。

他的教学法只有三步:

  1. 概念介绍:写代码之前,先说清楚"要做什么、为什么这样做";
  2. 引导性教程 :一步步做,全程编译和测试,边做边抓 Bug;
  3. 重复练习:先带你做一个敌人类型,再让你自己做另外三个。

第 2 步里藏着一句很有胆量的话:"笔者甚至会给你制造一些 Bug",让你提前认识它们长什么样。

这其实是"疫苗式教学":在安全的环境里感染一次,真上战场时就有抗体了。

90% 的 Bug 是手误

作者说他帮学生改 Bug 改出了肌肉记忆,现在能秒定位。常见的手误只有三类:

类型 例子 编译器的反应
拼写错误 tramsform 写成 transform 的亲戚 找不到标识符
大小写错误 Variable / variable / variAble 在 C# 眼里是三个词
漏写分号 int x = 1 后面没 ; 报错往往出现在下一行

为什么 C# 用分号而不是句号?因为句号已经被小数点占用了,还被"点语法"占用了:varName.subVarName.SubSubVarName。

漏分号这个坑最阴险,看个例子:

csharp 复制代码
void Start()
{
    int score = 0      // ← 少了分号
    Debug.Log(score);  // 编译器会在这里报错,但问题在上一行
}

这段代码在说明什么 :编译器的报错行号不等于错误行号。学会"往上找一行",能省掉大量抓头发的时间 🧠。

再往后,作者会布置一个真正上强度的作业:四周内,逼真还原一款经典游戏的机制与体验------《超级马里奥》《银河战士》《恶魔城》《口袋妖怪》,甚至初代《塞尔达传说》。

关键不是复刻,而是那句心理转变:

从"我在学习这本教程",变成"我想做成这件事情------现在我需要怎么做?"


五、首次运行:先玩,再干活

装完、激活许可(建议先激活免费版,把 30 天 Pro 试用留到第 34 章做 QuickSnap 时再用,因为那时需要漂亮的反射和着色器),Unity 会自动打开演示项目 AngryBots。

这个项目加载要几秒,期间窗口可能看起来假死------别慌,等它。

进游戏后按提示玩:

  • WASD 或方向键移动;
  • 枪口永远指向鼠标;
  • 左键开枪;
  • 想在圆形舱门前站几秒才开;
  • 有些地方要站到电脑前,让红色电线变绿。

玩的时候作者让你注意三样东西:

效果 描述 谁能看到
A 景深 一部分清晰,一部分模糊 仅 Pro
B 地板反光 尤其激光瞄准器的倒影 仅 Pro
C 动态雨滴 室外地面上的雨 免费版也能看到

这就是免费版与专业版"为数不多的区别之一"。作者的态度很务实:学习阶段,免费版够用。

还有两个技术点值得记一笔:

  • 动画合成:角色可以一边朝一个方向射击、一边朝另一个方向移动;
  • AI 寻径:敌人能绕过室内障碍找到你。

把游戏编译到网页

停止运行 → File > Build Settings... → 选 Web Player → 勾 Offline Deployment → 保存为 AngryBotsWebBuild → 等它处理完,浏览器自动打开。

作者的原话是"这样就大功告成了"。半个小时的下载 + 几次点击,你就拥有了一个能发给朋友看的网页版游戏。

最后一步:把窗口摆好

Unity 允许你自定义面板布局。右上角的 Layout 菜单里有一堆预设,本书的示例统一使用 2 by 3 。菜单里还有 Save Layout...、Delete Layout...、Revert Factory Settings。

别小看这一步。后面所有教程的截图都基于同一套布局------布局一致,你的眼睛才不用每次重新找东西。


六、小结

这一章其实干了四件事:

  • 装好环境,拿到许可;
  • 说清楚"为什么是 Unity、为什么是 C#"------两个选择都有可验证的理由,而不是信仰;
  • 用 AngryBots 让你先体验"完成度",再回头学"怎么做";
  • 把窗口摆成全书统一的样子。

如果只能记一句话,我选作者那句自嘲式的教学承诺:

我会故意给你制造 Bug,这样你以后遇到自己的 Bug 时,处理起来会更简单。

毕竟,游戏开发这门手艺,一半是创造,一半是和自己的手误搏斗 🐛。

相关推荐
天树星智源2 小时前
每个 token 各配其师:token 级多教师蒸馏拉高 5.9 分
人工智能
米饭是菜qy2 小时前
深度学习Transformer详细介绍
人工智能·深度学习·transformer
eric-sjq2 小时前
小思框架 · 30M 级长上下文新架构对比技术报告
人工智能·python·深度学习·语言模型
Kari112 小时前
Dify vs Coze开源版:企业级AI应用平台对比
人工智能·开源
AI视频工具指南2 小时前
AI视频的声音和画面怎么配合?先分清谁在传递信息
人工智能·aigc·音视频
云析赢指标公式网42 小时前
指标开发笔记|主图搭配双副图成套指标逻辑拆解
人工智能·笔记
奈落242 小时前
连错一个端口,Agent就“看不见”工具:从 n8n 的8种AI连接类型到 Dify 的插件审批复用,平台设计里的“隐形接线规则”怎么读
人工智能·agent·ai 编程
这是谁的博客?2 小时前
AI 加速器 RTL 数字系统设计深度解析:从 MAC 阵列 Verilog 实现到时序收敛与时钟功耗的芯片落地全链路
人工智能·macos·ai·verilog·数字ic设计·ai芯片·rtl
无所畏俱的老尹2 小时前
OpenAI 等支持 robots.txt 共享 AI 训练偏好信号:policy token 一次声明多厂商,落地仍待实现
人工智能·深度学习·机器学习·aigc