做游戏这件事,问的人多,真正动手的人少。我见过太多人卡在同一个地方:想做个游戏,打开引擎,面对满屏英文界面,三分钟后就关了。然后开始怀疑自己是不是该先去把编程语言学透,又或者是不是得先会画画、会作曲、会建模才配动手。
说句实在话,这些想法全错了。自己做游戏这件事,和“会写代码”之间的距离,比大多数人想象的要远,但也比大多数人想象的要容易够到。关键在于你得知道,做游戏需要的能力不是一个“编程技能”,而是一组技能的搭配,并且它们的优先级完全不同。
这篇文章我就把自己这些年做游戏、看别人做游戏的经验掰开揉碎讲清楚。如果你是个纯新手,连“变量”是什么都还没搞明白,这篇文章就是给你看的。
1. 先把“做游戏需要什么”这件事想明白:技能分层比技能种类重要
很多人一上来就问“做游戏是不是要先学C++”,这个问题本身就问偏了。做游戏不是写程序,写程序只是游戏制作这个链条里的一环。一个完整的游戏从无到有,涉及到的能力大概是这样的:
- 程序开发能力:让游戏跑起来,处理玩家输入、游戏逻辑、画面渲染、存档读档。这是硬技能,绕不开。
- 游戏设计能力:知道什么玩法好玩,怎么设计关卡、数值、成长曲线。说白了就是“游戏意识”。
- 美术资源能力:角色长什么样、场景如何布局、UI怎么设计。不一定要你画得多好,但你得能产出能用的东西。
- 音频与叙事能力:背景音乐、音效、剧情、对白。独立游戏里这往往是点睛之笔。
看着多,但对一个想自己独立做游戏的新手而言,真正的重点只有一个:先让一个简单游戏跑起来,获得完整的正反馈闭环。美术可以丑,音效可以没有,剧情可以不存在,但一个能从“点击开始”到“游戏结束”都顺畅走完的流程,才是你的第一目标。
如果你非要一次性把钱、程序、美术、设计全部搞完美再动手,那我可以负责任地告诉你:你永远做不完第一个游戏。这不是预言,而是我见过太多人的结局。
所以先把技能分层这件事想清楚。一个合格的个人独立游戏开发者,核心技能只有三个,按优先级排:
- 编程基础(能实现你想实现的玩法逻辑)
- 游戏引擎使用能力(能把场景、角色、UI拼起来)
- 游戏设计意识(知道怎么让玩家觉得好玩)
其余的(美术、音频、营销、发行)全部是“可延迟满足”的辅助项。等你的原型做出来之后,再回头补也来得及。
2. 编程基础怎么学才不算白学:从游戏需要的“最小语法集”出发
网上有一大堆编程入门教程,但绝大多数都学不到点子上。因为它们是为“软件工程师”设计的,不是为“游戏开发者”设计的。你不需要学完整个C++以后才开始做游戏,那好比要求一个人把整部《新华字典》背完了才允许他开口说话。
2.1 游戏中真正会用到的编程概念,其实只有几个
我拆过大量新手游戏的代码,发现用于游戏逻辑的语法,占比最高的就那么几类:
| 语法类别 | 在游戏里的作用 | 必要程度 |
|---|---|---|
| 变量与数据类型 | 记录玩家生命值、分数、金币数 | 必须 |
| 条件判断(if/else) | 判断碰撞是否发生、机关是否触发 | 必须 |
| 循环(for/while) | 遍历敌人列表、生成子弹带 | 必须 |
| 函数(方法) | 把攻击、跳跃、受伤拆成可复用的逻辑块 | 必须 |
| 数组/列表 | 存敌人的波次、背包里的物品 | 高频 |
| 面向对象(类) | 把“敌人”抽象为一个可批量生成的模板 | 高频 |
你仔细看,这里面没有指针、没有内存管理、没有“多线程”“网络编程”“设计模式”。这些东西在你做的第一个游戏里根本用不上。谁让你一上来就啃这些,基本等于劝退。
面向对象(类)这个特别值得单独说一句。游戏里到处都是“同类事物批量出现”的场景:一群小怪有相同的血量、攻击力、移动方式,如果一个个写逻辑代码,你会写到崩溃。用“类”把这个怪物的样子定义好,然后让它批量生成,就是面向对象的核心用法。这个思想只要你能在游戏场景里想明白一次,后面学什么都顺了。
2.2 学编程的实操顺序,跟着游戏需求走
我推荐的路线是这样的,每一段都能让游戏往前推进一步:
- 先学变量和函数,配合print(控制台输出)知道数据是怎么流通的。
- 立刻去找一个小型游戏引擎教程,比如做“接苹果”或“小球躲障碍”,把语法和实际游戏效果结合起来。
- 在学碰撞检测时回头补条件判断,你会发现if语句真的在起作用,而不是填空题。
- 在给游戏加敌人时学数组和类的用法,同一个敌人模板生成十只,你就懂“面向对象”的意义了。
- 循环往往在做“波次攻击”或“无限生成物品”时自然学会。
提示:别学完一整个编程课再动手做游戏。正确姿势是“学三课,做一个小功能;再学三课,再做一个小功能”,让知识点立刻有产出,这样大脑才有持续的正向反馈。
2.3 Python、C#、C++到底先学哪个
这是热搜里最常被问的问题。我的回答很直接:别从C++开始。C++是一门强大但陡峭的语言,它把你的注意力全部吸引到内存、指针这些底层细节里,而这些东西在游戏原型阶段几乎帮不上忙。
更合理的起点是:
- C#(配Unity):Unity是市场占有率最高的游戏引擎之一,教程多到看不完,C#的语法也相对友好。作为第一个引擎+语言组合,它的试错成本最低。
- GDScript(配Godot):Godot引擎的上手曲线最平滑,引擎本身免费开源,GDScript的语法贴近Python,新手用起来几乎没有阅读障碍,极其适合做2D游戏。这几年独立游戏圈里用Godot的人越来越多,社区生态也成熟了。
- C++(配Unreal):适合“我铁了心要进3A大厂”或者“我就是要做高画质3D大作”的人。但新手用它起步,大概率会被编译器和链接器折腾到怀疑人生。我建议玩过半款完整游戏之后再转到它,那时候你学C++的效率会高一个档次。
3. 游戏引擎是选Unity、Unreal还是Godot:脱离需求谈引擎就是耍流氓
引擎之争是游戏开发圈经久不衰的话题,每隔几天就有人吵起来。作为个人开发者,我的看法特别务实:选引擎看三件事——你要做什么类型、你手上的电脑跑不跑得动、文档社区够不够活跃。
3.1 三款主流引擎的横向对比
| 维度 | Unity | Unreal(UE 5) | Godot |
|---|---|---|---|
| 上手难度 | 中等 | 较高 | 低 |
| 适合游戏类型 | 全类型,2D/3D通吃 | 3D大作、高画质场景 | 2D极佳,3D够用 |
| 编程语言 | C# | C++(也可用蓝图可视化) | GDScript / C# |
| 硬件要求 | 中等,低配也能跑 | 高,推荐独立显卡 | 很低,旧电脑都能跑 |
| 资源商店/生态 | 成熟,素材多 | 素材多但要筛选 | 相对少但够用 |
| 商业化限制 | 收入超过阈值才收授权费 | 收入超过阈值才收授权费 | 开源无费用 |
基于个人开发者的视角,我给三条建议:
- 想做2D独立游戏、喜欢像素风或者轻量玩法:首选Godot。它最近几个版本发展极快,场景树的概念对新手友好,性能也够用,随手就能导出到Windows、Linux、网页、手机。
- 想做大型3D游戏、看重市场兼容性:选Unity。它有最庞大的教程库和企业级的资源管线,你卡住了随便搜都有答案。
- 你就是冲着高品质3A画面去的:选UE 5,用蓝图起步可以避开直接写C++的痛苦。UE 5的“蓝图可视化脚本”系统(生成节点连线)其实很适合新手理解逻辑,只是项目会比较大、加载比较慢。
提示:纠结“选哪个引擎”超过三天的人,大概率最后什么也没做。引擎只是工具,随便选一个,用一周时间跟着官方实例走完一遍,你自然知道它适不适合你。工具是越用越熟的,不是越挑越对的。
3.2 引擎的本质是什么?别被界面吓到
对于刚接触引擎的人来说,那一堆窗口——场景视图、游戏视图、资源面板、层级面板、检查器——看着特别吓人。但你只需要抓住一个核心就够:游戏引擎的本质是“做游戏的中控台”,它把显示画面、处理输入、播放声音、加载资源、物理碰撞这些底层操作全替你封装好了,你只需要用脚本告诉它“玩家按空格时角色要跳起来”就完事了。
如果你第几次打开引擎觉得无从下手,不要“系统学一遍引擎”,而是直接找一个《手把手带你做一个XX游戏》的系列教程,跟着做完一个完整的塔防或平台跳跃,你对引擎的恐惧会在七天内消失。
4. 第一个游戏到底怎么从零跑起来:不贪大,只做“能玩的东西”
这部分我想给一份新手真正能照着做的最小可玩流程。它不需要你有任何美术基础,也不需要什么高深数学,按着这个走,两周内你就能拥有一个可以给别人玩的成品。
4.1 玩法要“搓得动”:如果你的设计连自己都无法在三句话里讲清楚,立刻换一个
很多人的第一个游戏死在选题:“我想做一个开放世界ARPG,有技能树,有装备合成,有坐骑系统。” 这不是第一个游戏,这是你的第五个游戏。
第一支游戏选题的原则是:玩法闭环要短。下面这个表是我给新手推荐的选题,都是“两天能见原型,两周能见成品”的体量:
| 选题 | 核心玩法闭环 |
|---|---|
| 贪吃蛇 | 吃食物增加长度,撞墙或撞自己则死 |
| 打砖块 | 接球反弹击碎砖块,保持球不掉落 |
| 接苹果 | 左右移动接住下落的苹果,漏掉扣生命 |
| 平台跳跃 | 跳跃躲避障碍抵达终点 |
| 太空射击 | 左右移动射击,躲避敌机和子弹 |
| Flappy Bird式 | 点击让小鸟上升,松开则下落,穿过管道 |
这些玩法看起来“简单”,但它们都有完整的“玩家操作→系统反馈→分数变化→胜负判定”闭环,足够教会你游戏开发的完整流程。
4.2 从零实现一个“小球吃金币”的完整步骤拆解
我用Godot语言风格给一套最具体的新手流程,跟着做就能出结果。换成Unity的逻辑也完全一样,只是函数名不同。
第一步:建立场景结构。一个主场景(游戏世界)里放三样东西:玩家(一个可控制的物体)、游戏控制器(负责生成金币和判分)、UI界面层(显示分数和游戏状态)。
第二步:玩家控制逻辑。给玩家挂一段移动脚本,核心代码就四五行。以“键盘方向键控制上下左右移动”为例:
extends CharacterBody2D var speed = 300 func _physics_process(delta): var input_dir = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down") velocity = input_dir * speed move_and_slide()你完全不需要深究每一行的底层原理,只要知道:Input.get_vector读取键盘输入,velocity设置移动速度,move_and_slide让物体真的动起来。
第三步:碰撞检测与反馈。给金币(金币角色)一个Area2D区域检测,当玩家进入它的范围时触发信号;信号里写了“加分”和“消失”:
func _on_body_entered(body): if body.name == "Player": Global.score += 1 queue_free()这里最关键的体验是:你亲手让“玩家碰到金币→金币消失→分数增加”这个逻辑链条成立。这比背十遍“信号与槽”的概念都管用。
第四步:UI与游戏状态。加一个Label显示当前分数,再加一个“游戏结束”的条件(比如角色碰到敌人就结束),把整个流程闭环。
第五步:把它导出成exe或网页文件,发给朋友试玩。
这个过程走完一遍,你会获得比看十本编程书都更扎实的“技能实感”。因为你不是在“学技能”,你是在“做东西”。
5. 基础原型之外的能力补全:游戏设计、美术资源与Debug的默契配合
第一版跑通之后,游戏还远远称不上“好玩”。这时候你会遇到真正拉开差距的问题:手感、节奏、成长反馈。这部分的技能点,反而在“程序能力”之外。
5.1 游戏设计的“最小可行玩法”意识
很多没有做过游戏的人以为,玩法是“想出来的新点子”。但实际上,大部分好玩的游戏,都是把一个普通玩法打磨到了极致。
我举一个最简单的例子:同样是“像素鸟”式的点击跳跃小游戏,为什么有的就是让人上瘾,有的玩十秒就删?差别往往在于:
- 跳跃的重力曲线:下落加速度太大,玩家来不及反应;太小,又缺乏爽感。
- 障碍密度:每根柱子距离多远、缝多宽,决定了“失败感的节奏”。
- 即时反馈:每过一根柱子时有没有清脆的计数音效或镜头微动,这决定了成就感。
这些“数值调整”的功夫,就是游戏设计能力。我的建议是:别去啃《游戏设计艺术》这种大部头,先把自己的游戏数值来回调,调到“玩三轮还想再开一局”的程度。经历一次这种调优,你对游戏设计的理解就比看一百个理论帖都深。
5.2 美术资源:不会画画的人,可以用这四招
你说你美术为零?没关系。独立游戏领域,美术的“够用”标准比大多数人想的低得多:
- 程序化生成素材:用免费的Aseprite、Piskel或在线像素画工具做简单的角色和卡通图块。像素画最大的好处是“丑得不那么显眼”,而且自带复古风格滤镜,玩家的容忍度极高。
- 免费素材商店:Unity Asset Store、itch.io、Kenney.nl上有海量免费素材,很多质量相当能打,足够撑起你的第一款游戏。
- 几何形状组合:圆形当角色、方块当地面,颜色区分敌我,用极简风格做完整款游戏。很多好评连连的独立游戏(说得就是你,几何风跑酷)就是这么干的。
- AI辅助生成:如果你肯花时间研究“AI生成可商用像素素材”的提示词写法,出图效率现在比五年前高出几个量级。
5.3 Debug能力:这是靠踩坑练出来的“第六感”
Debug(排除程序错误与逻辑错误)是游戏开发里你每天都会做的事。新手最容易犯的“Debug恐惧症”,是遇到报错就蒙。但实际上,游戏引擎的报错往往已经指明了方向:哪一行代码出错了、什么类型的错误、哪个对象是空的。
我分享一个自己踩过的典型坑:物理引擎碰撞失效。调试过程是——确认角色Area2D是否勾选了“monitoring”,确认CollisionShape2D是否画了范围,确认层的掩码(collision_mask)是否包含了目标层,最后发现是因为忘记了给地面加静态碰撞体。这种问题排查三次之后你就会形成肌肉记忆。
新手Debug的清单式顺序:
- 读报错信息,它通常会告诉你文件名和行号。
- 在关键位置加输出调试信息,打印变量值,确认它走到哪一步卡住了。
- 二分法注释:把逻辑每半段注释掉,看哪一半还在工作,缩小问题范围。
- 回滚测试:最近改了哪个脚本,复原它看是否恢复。八成问题出在“最近改的那次”。
提示:Debug能力不是天赋,是踩坑的积累。每遇到一次报错,解决后记一条笔记。半年之后你就是“排错熟练工”。
6. 一个经典案例的完整拆解:Flappy Bird(像素小鸟)从0到可发布全流程
光讲理论没有说服力。我把一个经典中的经典——Flappy Bird——的完整制作思路拆给你看。为什么选它?因为它的代码量极小(核心代码不超过200行),玩法闭环完整,美术素材一两张图就能搞定。
6.1 核心逻辑拆解
Flappy Bird的玩法本质就四个系统:
| 系统 | 实现方式 |
|---|---|
| 小鸟受重力下落,点击让小鸟获得一个向上冲量 | 每帧给小鸟施加向下的重力加速度;点击时给它一个瞬时向上的速度 |
| 水管生成 | 每隔一定时间,在随机高度生成一对上下水管,并持续向左移动 |
| 碰撞判定 | 小鸟碰到水管或地面则游戏结束 |
| 计分系统 | 小鸟通过一对水管的中间时加一分 |
6.2 核心代码逻辑(以GDScript为示例)
extends CharacterBody2D var gravity = 900.0 var flap_strength = -250.0 var score = 0 func _physics_process(delta): # 重力持续作用 velocity.y += gravity * delta move_and_slide() # 点击屏幕/按空格键时向上飞 if Input.is_action_just_pressed("ui_accept"): velocity.y = flap_strength func _on_pipe_body_entered(body): # 碰到水管,游戏结束 get_tree().paused = true GameUI.show_game_over(score)# 水管生成脚本(挂在生成器节点上) extends Node2D var pipe_scene = preload("res://Pipe.tscn") var spawn_timer = 2.0 func _process(delta): spawn_timer -= delta if spawn_timer <= 0: _spawn_pipe() spawn_timer = randf_range(1.2, 2.5) # 随机间隔避免节奏太死板 func _spawn_pipe(): var pipe = pipe_scene.instantiate() pipe.position = Vector2(400, randi_range(150, 350)) add_child(pipe)6.3 调优的“手感”体会:做完能玩之后,把70%时间花在这
很多教程到这里就结束了,但我必须多说一句:能跑只是起点,好玩才是终点。你在新手上路阶段最宝贵的练习,是去调下面三个参数:
- 重力值调大,小鸟下落更快,操作难度上升;调小则更“飘”。
- 点击时给的向上速度和重力要保持某种平衡——太强会飞出去,太弱会感觉“手都按酸了还是沉底”。
- 水管的间隔和高度随机范围:间隔太窄难如登天,太宽又毫无挑战感。
我实打实告诉你,我当年调Flappy Bird手感到“能连续玩五分钟不腻”这个状态,花了整整一个下午。但你从这个下午里学到的东西,比做完十个“照着教程抄的作业”都多。
7. 游戏开发学习中一定会踩的认知误区:C++与C#的区别、Python的作用、PLC和单片机算不算走偏
热搜词里有个很有意思的组合:一边是“游戏开发c++和c#的区别”,一边是“plc编程”“单片机ai在线编程”。这说明很多人其实在“游戏开发”和“嵌入式编程”之间反复横跳。我在这里把几个认知误区一次性说透。
7.1 C++和C#,到底差在哪
字面上C++比C#多两个加号,但它们在游戏领域的定位完全两回事:
| 维度 | C++ | C# |
|---|---|---|
| 编译方式 | 编译为机器码,性能更高 | 编译为中间语言,运行时编译,性能略低但开发效率高 |
| 引擎 | UE 5的主流语言 | Unity的主力语言 |
| 学习曲线 | 陡峭,需要理解指针和内存管理 | 平缓,自动内存管理,适合业务逻辑 |
| 适合阶段 | 有一定基础后再切入 | 新手第一个引擎语言,非常合适 |
| 典型岗位 | 引擎开发、3A客户端 | 商业游戏逻辑、独立游戏 |
所以如果你看到“某个人用C++做了一个3D大作”,请记住他大概率不是新手——他已经熬过了漫长的前期积累才敢碰C++。新手选C# + 一个成熟引擎,是用最小的阻力换取最多的成品率,这是最理性的选择。
7.2 “我要不要先学Python?”——Python在游戏开发里到底是干嘛的
Python在游戏开发圈里的定位有点微妙。它本身有Pygame、Godot的GDScript(语法近似)这些游戏方向,市面上也有大量“Python小游戏”教程,但正经商业游戏很少用Python写核心。
我的建议是:你完全可以先用Python/Pygame做几个文字冒险或极简小游戏来建立编程感觉,但别把它当终点。Python的价值在于语法极简,适合你训练“拆解玩法→写成代码流程”的思维。等这种思维成立了,再切换到C#或GDScript,你会发现很多概念是相通的——变量、循环、函数、类,换语言只是换一层皮。
换句话说,Python是很好的“编程思维练习场”,而C#或GDScript才是你真正“做游戏”的主战场。
7.3 PLC、单片机、嵌入式C编程,适不适合游戏开发者
连着几个热搜词都指向PLC和单片机,我理解很多人可能之前学过嵌入式,或者觉得“单片机都能控制硬件了,做游戏肯定也不在话下”。这个想法对一半:编程底层思维是通用的,但它们的应用方向差别巨大。
PLC/单片机编程处理的是“传感器读取、继电器控制、时序逻辑”,而游戏开发处理的是“事件驱动、物理模拟、实时渲染”。就像你会修汽车发动机不代表你会开赛车——技术栈有交集,但目标是两码事。如果你纯粹对“写代码控制硬件”感兴趣,PLC方向本身也是好赛道,但别指望它能直接迁移到游戏开发上。
如果你在“游戏开发”和“嵌入式开发”之间徘徊,我劝先问自己一个问题:你更享受“创造一个虚拟世界”的乐趣,还是“让现实中的设备动起来”的乐趣?这两个答案指向完全不同但都值得投入的方向。
8. 从第一个游戏到持续进步:你的学习路线图与资源选择
写到这里,我想给一张可执行的学习地图。它不是“学满十个月才能做游戏”的漫长计划,而是每走一步都有产出的短反馈循环。
8.1 12周自驱路线表
| 周次 | 核心任务 | 产出物 |
|---|---|---|
| 第1周 | 选定引擎,完成官方“制作你的第一个游戏”教程 | 一个引擎自带的示例游戏跑起来 |
| 第2周 | 自己从空项目做一款“接苹果” | 可玩的接苹果游戏 |
| 第3周 | 给游戏加UI、音效、生命值 | 有完整反馈闭环的小游戏 |
| 第4周 | 复刻一款经典小游戏(贪吃蛇/太空射击) | 像素级复刻的经典玩法 |
| 第5周 | 找朋友试玩,记录他们卡在哪、哪里觉得无聊 | 一份真实的玩家反馈记录 |
| 第6周 | 针对反馈调优数值、节奏、难度 | 一个比上周明显更好玩的版本 |
| 第7周 | 换一个题材/玩法,复现之前的完整流程 | 第二个完整小游戏 |
| 第8周 | 学习“类”和“场景管理”,把你的游戏重构得更规范 | 代码质量提升后的版本 |
| 第9周 | 尝试设计一个属于自己的原创小玩法 | 一个带个人烙印的原型 |
| 第10周 | 研究所选引擎的材质/光照/特效进阶功能 | 画面表现力提升 |
| 第11周 | 学习导出与上架流程,发布首个正式版本 | 一个别人能玩到的游戏 |
| 第12周 | 复盘全流程,挑一个你认为最值得优化的点深入学习 | 下一阶段的个人学习计划 |
最关键的策略是:每周必须有“可玩的产出”,而不是“学会了一个概念”。做游戏和做学问最大的不同在于,它是典型的“创作导向”技能——你必须靠一件件作品去推动认知升级。
8.2 资源怎么选:警惕“收藏即学会”
现在免费的学习资源多到爆炸,新手真正的问题反而不是“找不到教程”,而是“教程太多,收藏了等于学过了”。
我给你的筛选标准就三条:
- 看发布时间:挑近两年的教程,引擎版本迭代快,三年以上的教程很多接口都过时了,照着做会报一堆错。
- 看是否有最终成品:如果教程没有展示一个完整的最终游戏效果,多半是讲概念的,不适合新手。
- 跟定一个人吃到通关:别今天跟A学Unity,明天跟B学Godot,多引擎横跳是最傻的学习方式。选定一个系列,从开篇跟到完结,比看一百个碎片视频都强。
顺带说一句,AI提示词(你会在热搜里看到“AI编程”“ai编程提示词”)现在对游戏开发的学习也有真实帮助——遇到不懂的报错、想让AI帮你生成一段平台跳跃的代码逻辑,都可以问。但记住AI是你的助手,不是你的替代品。如果连“AI写的东西为什么这么写”都不追求理解,你做游戏的技能永远不会长在自己身上。
9. 个人经验收尾
做了这么多年项目,带过不少新人,我最大的心得是:制作游戏这项技能的玄学门槛,远没有想象中那么高;但它的“坚持成本”远高于多数人的预估。
我见过很多非常有天赋的新人,第一个原型做得又快又好,却在第二个游戏选题上反复纠结,最后项目搁置。也见过不少资质平平、代码也写得很笨的人,因为坚持“每周产出一个可玩乐的原型”,一年多以后做出了Steam上架的作品。差别不在天赋,在“能不能持续产出”。
所以,如果你看完这篇文章打算动手,我的建议就三条:选一个最小的玩法、选一个免费引擎、给每周设置一个“给朋友试玩”的截止日。把“完成”这件事看得比“完美”重要得多,因为只有完成过一次完整的游戏,你才知道自己缺的到底是什么、接下来该往哪个方向补。
最后分享一个我自己的小诀窍:做第一个游戏的时候,没必要执着于“原创玩法”。复刻经典小游戏不是可耻的事,反而是最有效的训练——把别人设计好的成熟玩法完整还原一遍,你会学到数值、节奏、反馈机制里那些看不见的门道。原创的灵感,往往就会在你复刻完成之后的某次调优中,突然自己蹦出来。