10. 写给完全没编过程的你
完全没接触过编程的人,看到「写脚本」三个字往往会有一秒的紧张反应。屏幕上密密麻麻的英文符号、看不懂的报错红字、需要记住的「语法规则」,这些印象大多来自影视作品和那些喜欢炫技的同学。
实际编程没有那么神秘。这一章不写代码,先把心里那几个问号拆开。
程序就是写下来的菜谱
Section titled “程序就是写下来的菜谱”家里那本菜谱写糖醋里脊:先切肉,腌十分钟,开火,下油,炸两遍,调汁,倒进去翻炒,出锅。一行一行,前后顺序固定。换厨房、换灶台、换锅,按这步骤做出来的味道大致一样。
程序也是这种东西。一段段写下来的指令,让电脑按顺序一条一条执行。
跟人不同的地方有两个:
- 电脑只会照字面办事。 菜谱写「翻炒至断生」,老厨师能凭经验判断什么叫断生;电脑读到「翻炒至断生」会原地卡住,因为它不知道怎么定义这件事。给程序的每一步都得是非常具体的动作。
- 电脑不会跳过步骤,但也不会自己补漏。 菜谱漏写了「先开火」,人会下意识补上;电脑会真的不开火直接下油,然后告诉你它油已经下了,等下一步。
明白了这两点,编程里九成的「为什么没按预想跑」都能想通。
三种最基本的指令
Section titled “三种最基本的指令”复杂的程序,归根到底由三种东西堆出来:记下一些东西、做判断、重复做。 名字以后会换,本质就这三件。
记下一些东西:变量
Section titled “记下一些东西:变量”写菜谱时,「肉切成 200 克」是个很常见的写法。「200 克」就是一条信息。如果整本菜谱里反复用到这个数,作者通常会在开头写「主料:里脊 200 克」,后面正文里只说「主料」,不再每次重复 200。
程序里这种「先取个名字、后面用到时引用名字」的做法叫变量。
血量 = 100主灯颜色 = 暖黄是否下雨 = 是变量好处有三个:第一,名字让代码可读;第二,要改时只改一处;第三,程序运行过程中可以更新它的值。比如玩家被打了一下,「血量 = 90」,再被打一下,「血量 = 80」。
VRChat 世界里玩家进来一下、走出去一下,这种「变化的状态」全用变量表达。
做判断:条件
Section titled “做判断:条件”菜谱常常会出现「如果……就……」。
「如果肉腌过夜,盐少放一点。」
「如果汁太稠,加点水。」
程序里这叫条件判断,常用形式是 if。
如果 血量 == 0: 主角倒下,弹出复活按钮只有满足条件,缩进里那段才会执行;不满足就跳过。if 还可以接一个 else,表示「否则就这样」。
如果 是否下雨: 打开屋檐下的灯否则: 关掉屋檐下的灯VRChat 世界里几乎每一种「按情况反应」的逻辑,最底层都是 if。门锁着才打不开、按钮还在冷却时按了没反应、玩家在区域里才播放音乐,全是判断。
重复做:循环
Section titled “重复做:循环”菜谱写「翻炒一分钟」是个简化说法,真正的动作是把锅铲来回挥几十下。「重复某个动作 N 次」这件事程序里太常见,干脆造了一个专门的语法叫循环。
重复 20 次: 在场景里复制一个发光球循环可以是「重复固定次数」,也可以是「重复直到某个条件满足为止」。前一种叫 for,后一种叫 while。VRChat 里有时要给十个出生位置依次分配玩家、有时要在一组按钮里挨个找哪个被按下,循环就是干这个用的。
把一段流程打包:函数
Section titled “把一段流程打包:函数”写菜谱时如果有一组动作反复出现,作者会专门起个名字。「调料汁:醋两勺、糖三勺、生抽一勺,搅匀。」后面正文里只说「调好料汁」,不重新列三遍配方。
程序里这种「把一段动作打包起来,后面通过名字调用」的东西叫函数,也叫方法。
函数 调料汁(): 取醋两勺 取糖三勺 取生抽一勺 搅匀
主流程: 切肉 调料汁() 炸两遍 倒入料汁 翻炒函数可以接受一些参数,类似菜谱里写「这道菜按 N 人份做」时,N 是变化的输入。函数也可以返回一个结果给调用者,比如「测一下油温」会返回一个温度数字。
VRChat 脚本里随处可见的 Start()、Update()、Interact() 都是函数。它们是 VRChat 客户端在特定时刻替作者调用的,作者要做的是写好「被调用时执行什么」。
VRChat 脚本多数是在等事件
Section titled “VRChat 脚本多数是在等事件”零基础读者很容易把程序想成「从第一行一直读到最后一行」。有些程序确实接近这样,比如命令行小工具。但 VRChat 世界里的脚本更像一张值班表:平时挂在物体上等着,事件发生时才执行对应函数。
世界加载完成 → 调 Start()每一帧刷新 → 调 Update()玩家按 Use 键 → 调 Interact()有玩家进入房间实例 → 调 OnPlayerJoined(player)所以写 VRChat 脚本时,常问的问题是:「这段代码应该挂在哪个事件下面」。按钮逻辑放 Interact(),一次性初始化放 Start(),持续移动放 Update()。这个分法比背语法更早用上。
把相关的东西归在一起:类
Section titled “把相关的东西归在一起:类”到这里已经能描述大部分简单逻辑了。但项目稍微大一点会出现新问题:变量和函数太多,互相之间没有组织。
回到厨房比喻。一个职业厨房里不会把所有刀、所有锅、所有调料堆一桌;会按用途分区。砧板区放刀和砧板,灶台区放锅和勺,调料台放罐和瓶。每个区域里只放跟这个事有关的东西,找起来快,互相不打架。
程序里类似的分区单位叫类。一个类把相关的变量和函数归到一起。
类 玩家: 数据: 血量 = 100 位置 = (0, 0, 0) 动作: 受伤(伤害): 血量 = 血量 - 伤害 移动到(目标位置): 位置 = 目标位置类是 C# 这门语言里最重要的组织单位,也是 UdonSharp 写脚本的基本单位。第 11 章会落到具体语法,这里先认识到「类」就是「相关变量和函数的归类袋子」。
报错是程序唯一可靠的反馈方式。它代表程序在某一步发现「按字面办事」做不下去了,把现场信息抄给作者看。
报错信息里通常包含三件事:
错误类型:哪类问题错误位置:哪个文件第几行现场信息:当时变量长什么样读懂这三件事的能力,比写得一手漂亮代码重要得多。第 12 章和第 40 章会再碰这件事,这里先把心理预期摆好:写代码的人每天都在跟报错打交道,老手只是看一眼就知道大概问题在哪,不是不报错。
你不需要先成为程序员才能开始
Section titled “你不需要先成为程序员才能开始”VRChat 世界的脚本,绝大多数是几十行的小段。控制一盏灯的开关、计一个分、记录玩家上次站在哪个区域。它们不需要算法竞赛级别的能力,更接近「写一份具体的工作流程」。
读到这里能听懂的话,已经具备了开始读真正 C# 语法的心智准备。语法是用来表达上面这些朴素思路的工具(变量、判断、循环、函数、类),只是要换成机器认得的写法。
下一章把这些朴素思路落到 C# 的具体写法上。落到代码之后,会发现一直在做的事,比想象中近得多。