尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

非科班生如何用Unity做一款公交互动叙事游戏

非科班生如何用Unity做一款公交互动叙事游戏 1. 一个新媒体学生为什么会去做一款公交游戏先坦白讲我本科学的是网络与新媒体课程表里跟“游戏开发”四个字沾边的只有一门选修的交互设计基础。Unity是自学的C#是边做边查的美术是拿Canva和Figma硬凑的。所以当我说“我做了一款公交游戏”的时候你脑子里浮现的那种带物理引擎、有 realistic 光影、能联机对战的画面可以先放一放——它更像是一个用游戏外壳包装起来的互动叙事作品核心不是操作快感而是让玩家在等车、挤车、坐过站这些日常场景里重新看见那些被忽略的城市细节。这个项目的起点其实特别朴素。大二下学期有一门叫“数字叙事”的课期末作业要求做一个“非线性的、可交互的叙事作品”。班里大部分同学选了H5图文、短视频或者播客我那时候正好每天坐三趟公交去实习早高峰的拥挤、晚班车的空旷、司机突然的急刹、后排阿姨外放的短视频声音这些碎片在我脑子里攒了很久。我就想能不能把这些体验做成一个可以“玩”的东西不是模拟驾驶那种硬核向的而是让玩家扮演一个普通的公交乘客在几站路的行程里遇到不同的人、触发不同的小事件、做出一些微不足道的选择。关键词里没有技术热词这反而让我松了一口气。因为这意味着我不需要去卷什么“次世代画面”“开放世界”“多人联机”我可以把精力全部放在氛围营造和叙事节奏上。公交这个场景本身就自带一种奇妙的张力它是一个临时的公共空间陌生人被迫共享一段封闭时间每个人都在扮演“乘客”这个角色但每个人的目的地、心情、状态又完全不同。这种“熟悉的陌生感”是叙事最肥沃的土壤。所以这篇文章不是一份正经的游戏开发教程更像是一个新媒体背景的学生用非科班的工具和思路把“公交”这个日常场景做成可交互体验的完整复盘。我会讲清楚我用了什么工具、为什么这么选、踩了哪些坑、哪些设计决策是事后看来特别对的、哪些是纯粹运气好。如果你也是非技术背景但想做点互动内容的人这篇应该能给你不少可以直接抄的作业。2. 把公交场景拆成可玩的零件我的设计拆解逻辑2.1 为什么不做“模拟驾驶”而做“乘客视角”一开始我也想过做驾驶模拟。毕竟公交游戏嘛开车不是最自然的吗但我很快否掉了这个方向原因有三个而且每一个都跟我的能力和资源直接相关。第一驾驶模拟的核心是物理反馈。油门响应、刹车距离、方向盘回正力度、后视镜视野、乘客在车厢里的惯性晃动——这些东西要做到“不假”需要大量的参数调校和物理引擎知识。我试过用Unity的WheelCollider搭了一个最基础的公交车模型结果车开起来像在冰面上漂移转弯半径完全不对刹车点头严重到乘客会穿模。调了三个晚上放弃了。第二驾驶模拟的叙事密度太低。玩家在开车的时候注意力全在路况和操作上根本没有余力去关注“车厢里发生了什么”。而我想做的恰恰是让玩家去注意那些细节前排学生在背单词、中间的大叔在打瞌睡、后门旁边的情侣在小声吵架。如果玩家在开车这些内容就全被浪费了。第三也是最重要的一点乘客视角天然带有“观察者”的叙事优势。你坐在座位上或者站在车厢里视线是自由的你可以看窗外、看手机、看别人、看自己的鞋。这种“无所事事但又必须待着”的状态恰恰是公交体验的精髓。玩家不需要“操作”什么只需要“存在”和“选择看哪里”。这让我可以把交互做得极轻把叙事做得极重。所以最终的设计是玩家扮演一个没有名字的乘客从上车刷卡开始到下车结束中间经过若干站。每一站会有人上车、有人下车车厢里的“生态”会发生变化。玩家可以点击车厢里的不同区域来“观察”每次观察会触发一段简短的文字描述或者一个小动画。没有失败条件没有分数没有时间限制。你唯一要做的就是“坐完这趟车”。2.2 公交线路即叙事骨架站点、时间与事件的三层结构确定了乘客视角之后下一个问题就是这趟车到底怎么“走”我一开始想得很复杂想做一个开放的城市地图玩家可以自由选择坐哪路车、去哪一站。但很快发现开放世界对叙事来说是灾难——玩家会迷路会错过关键事件会因为不知道“该干什么”而退出。所以我把它收窄成了一条固定的、线性的、但内部有分支的线路。具体来说我设计了三个层次的结构第一层是物理站点。整条线路一共八站从“起点站”到“终点站”。每一站有名字名字都是我从真实公交站牌上“偷”来的比如“槐树街口”“人民公园东门”“纺织厂宿舍”。这些名字自带画面感玩家一看就能脑补出大概的城市区域。第二层是时间推进。每一站之间有一个“行驶时间”大概是15到30秒的游戏内时间。在这段时间里车窗外的景色会缓慢滚动我用的是2D视差滚动的背景车厢里的光线会变化从早晨的冷白到傍晚的暖黄乘客的密度也会变化。时间推进的作用是给玩家一个节奏感让他们知道“这一站和下一站之间是有过程的”而不是瞬间传送。第三层是事件触发。每一站都会触发至少一个“车厢事件”。事件分三类观察类玩家点击某个乘客看到一段描述、对话类两个NPC之间自动发生一段对话玩家可以旁听、选择类玩家需要做一个微小的选择比如“让座”还是“假装没看见”。这三类事件交替出现保证每一站都有新鲜感但又不至于信息过载。这三层结构的好处是它把“坐公交”这个行为拆解成了可管理的单元。我不需要做一个完整的城市只需要做八个“切片”每个切片里放两到三个事件。工作量可控叙事密度也够。2.3 用“观察”代替“操作”交互设计的减法思路前面说了这个游戏的核心交互是“观察”。但“观察”这个词其实很模糊具体到实现上我做了很多减法。最开始的版本里我设计了一个“注意力条”。玩家每次观察会消耗注意力注意力耗尽就需要“休息”其实就是等几秒。这个设计的初衷是增加一点策略性让玩家不能一次性把所有内容都看完。但测试的时候所有试玩的人都在问“为什么我不能看了我还没看完呢。”这个反馈让我意识到在叙事类体验里任何限制玩家获取信息的机制都是负反馈。玩家是来“看故事”的不是来“管理资源”的。所以我直接把注意力条删了改成无限观察。第二个减法是把“移动”去掉了。原本我想让玩家可以在车厢里走动从车头走到车尾从左边走到右边。但实现起来发现3D空间里的移动会带来视角问题、碰撞问题、遮挡问题而且玩家在移动的时候会错过很多静态的细节。所以我改成了固定视角点击热点。玩家坐在一个固定的座位上视线范围内有若干个可点击的热点比如前排的乘客、窗外、自己的手机、扶手。点击热点就触发对应的内容。这个方案实现简单而且玩家的注意力始终在“内容”上而不是“操作”上。第三个减法是去掉了所有UI元素。没有血条、没有任务列表、没有小地图、没有按钮。唯一的UI是一个极简的“下一站”提示出现在屏幕底部用很小的字号。我想让玩家尽可能沉浸在“车厢”这个环境里而不是被各种界面元素提醒“你在玩游戏”。这个决定在测试的时候争议很大有人觉得“不知道能干什么”但我觉得这恰恰是公交体验的一部分——你上了车也不知道接下来会发生什么你只能等着。3. 非科班工具链我用什么把想法变成了能跑的东西3.1 引擎选型为什么Unity而不是Godot或GameMaker引擎选择上我纠结了很久。当时摆在面前的有三个选项Unity、Godot、GameMaker Studio。GameMaker是最容易上手的拖拖拽拽就能做出2D游戏但它的强项是平台跳跃和动作类对于我这种“点击触发文本”的叙事游戏来说它的很多功能是冗余的而且它的文本排版和字体渲染能力比较弱中文支持也不够好。Godot是开源的轻量2D能力强GDScript学起来也快。我试了一个周末确实能很快搭出一个可点击的场景。但问题是Godot的中文社区资源相对少遇到问题查资料比较费劲而且它的UI系统Control节点虽然灵活但对于我这种需要大量文本排版和动态内容加载的场景来说配置起来比较繁琐。最后选Unity原因很实际教程多、资源多、踩坑有人问。我自学的时候B站和YouTube上有大量中文的Unity入门教程遇到问题搜索“Unity 点击 触发 文本”能出来几十个结果。而且Unity的TextMeshPro组件对中文排版的支持非常好行距、字距、富文本标签都很完善这对于一个以文字为主要载体的叙事游戏来说太重要了。版本上我用的是Unity 2021 LTS。为什么不追新因为LTS版本稳定插件兼容性好而且网上大部分教程都是基于LTS的。我建议非科班的朋友也选LTS不要为了尝鲜去用最新的Tech Stream版本那些版本经常有API变动和插件不兼容的问题对新手来说是纯粹的折磨。3.2 美术资源CanvaFigma免费素材库的拼凑方案美术是我最弱的一环。我没有任何绘画基础手绘板买回来用了两次就吃灰了。所以我的策略是能用现成的就用现成的能拼凑的就拼凑实在不行就用极简风格糊弄过去。车厢内部的背景我用的是Figma画的矢量图。Figma的好处是免费、网页端、操作简单画几个矩形和圆角就能拼出座椅、扶手、车窗。颜色上我选了一套低饱和度的配色灰蓝、米白、暗橙整体偏“旧”和“暖”符合公交车的质感。乘客的立绘是最头疼的。我一开始想用AI生成但试了几个工具生成的人物要么风格不统一要么细节很奇怪比如手指数量不对。后来我找到了一个叫“Open Peeps”的免费插画库里面全是手绘风格的人物线稿可以自由组合发型、衣服、姿势。虽然风格比较“卡通”但胜在统一而且免费可商用。我把这些人物导入Figma改了一下颜色加了一些简单的阴影看起来居然还挺协调。车窗外的景色我用的是视差滚动的2D背景。素材是从一个免费的游戏素材网站Kenney.nl下载的城市剪影包然后用Photoshop拼成了一条长图。滚动的时候近处的建筑动得快远处的动得慢形成一种伪3D的纵深感。这个技巧在2D游戏里非常常见实现起来也简单就是两个图层以不同速度移动而已。音效方面我用了Freesound.org上的免费音效。公交车发动机的怠速声、车门开关的气动声、报站的提示音、乘客上车的脚步声、刷卡机的“滴”声——这些音效单独听都很普通但叠在一起之后车厢的“氛围感”立刻就出来了。我强烈建议做场景类体验的朋友在音效上不要省钱也不要省时间因为听觉对氛围的贡献至少占一半。3.3 数据驱动的内容管理用JSON把文本和代码分开这个项目里我做得最对的一个技术决策就是把所有的文本内容从代码里抽出来放到JSON文件里。一开始我是把文本直接写在C#脚本里的比如textComponent.text 你看到一个学生正在背单词;。写了十几个之后我发现改起来太痛苦了。每次改一句话都要重新编译而且文本和逻辑混在一起找起来很费劲。后来我改成了JSON驱动。结构大概是这样的{ stops: [ { id: stop_01, name: 起点站, events: [ { type: observe, target: student, text: 他手里的单词书已经翻到最后一页了书角卷得很厉害。, condition: always }, { type: dialogue, speaker_a: 阿姨, speaker_b: 司机, lines: [ 师傅这车到不到纺织厂, 到的你坐稳了。 ] } ] } ] }这样做的好处太多了。第一改文本不需要动代码直接在JSON里改保存就能生效。第二我可以把JSON发给不懂编程的朋友让他们帮忙写文案他们只需要按照格式填内容就行。第三后期如果要做多语言只需要换一个JSON文件。第四调试的时候可以快速跳过某些事件只需要在JSON里把对应的条目删掉或者改条件。对于非科班开发者来说数据驱动是降低维护成本的最有效手段。你不需要懂什么设计模式只需要记住一个原则会变的东西不要写死在代码里。4. 开发过程中那些让我想砸键盘的坑4.1 中文文本的换行与排版TextMeshPro的坑与解中文排版在Unity里是个大坑我在这上面至少浪费了五个晚上。第一个问题是自动换行。TextMeshPro默认的换行逻辑是基于英文的它会在空格处断行。但中文没有空格所以它要么不换行文字溢出屏幕要么在很奇怪的地方断行比如把一个词拆开。解决办法是在TextMeshPro的组件设置里把“Word Wrapping”打开然后把“Overflow”设为“Ellipsis”或者“Truncate”。但这样还不够因为中文的断行规则更复杂标点符号不能出现在行首某些词不能拆开。我最后的方案是手动控制换行在JSON文本里用\n来指定换行位置。虽然麻烦但效果最可控。第二个问题是字体。Unity自带的Arial字体对中文的支持很差很多汉字显示不出来。我换成了思源黑体Source Han Sans这是一个开源的中文字体字重齐全显示效果很好。但导入的时候要注意中文字体文件很大直接导入会导致包体膨胀。我的做法是只提取用到的字符用FontSubsetPack工具把字体文件缩小到几百KB。第三个问题是富文本标签。我想让某些关键词高亮显示比如“你看到一个学生正在背单词”。TextMeshPro支持富文本但标签的写法跟HTML不太一样而且嵌套的时候容易出错。我踩过的坑是color标签不能嵌套b标签否则会报错。解决办法是把样式拆开写比如bcolor#FF0000学生/color/b先加粗再变色顺序不能反。4.2 点击热点的判定为什么我的按钮总是点不中点击热点看起来很简单不就是给一个区域加个Collider然后检测点击吗但实际做起来问题一大堆。第一个问题是Collider的大小和位置。我一开始用的是BoxCollider2D手动调整大小和位置。但车厢里的乘客位置是动态的每一站都会有人上车下车Collider也要跟着变。手动调了十几个之后我放弃了改成了用代码动态生成Collider。每个乘客在生成的时候根据它的Sprite尺寸自动计算Collider的大小和位置。这样虽然不够精确但至少不会出现“点不到”的情况。第二个问题是点击穿透。当两个热点重叠的时候点击会同时触发两个事件。比如“车窗”和“窗外的建筑”重叠了点一下会同时触发“你看了一眼窗外”和“你注意到远处有一栋红色的楼”。解决办法是给Collider设置层级用Physics2D.raycast的时候只取最上面的一层。或者更简单粗暴在触发一个事件之后暂时禁用其他所有热点等事件结束再恢复。第三个问题是移动端的触摸适配。虽然我主要是在PC上开发和测试但最终是想让玩家在手机上也能玩。手机上的触摸和鼠标点击不一样手指的接触面积大而且会有滑动和长按的误触。我的解决方案是把点击判定区域放大至少是视觉元素的1.5倍。同时加了一个点击延迟按下之后等0.1秒再触发避免滑动的时候误触。4.3 场景切换时的状态丢失一个让我通宵的Bug这个Bug是我整个开发过程中遇到的最严重的问题直接导致我通宵了一个晚上。情况是这样的我的游戏是分场景的每个站点是一个独立的Unity Scene。玩家从“起点站”进入“第二站”的时候会加载新的场景。但问题是玩家的“观察记录”在场景切换的时候丢失了。比如玩家在起点站观察了一个学生到了第二站这个学生还在车上但玩家再点击他的时候触发的却是“第一次观察”的文本而不是“再次观察”的文本。我一开始以为是变量没有保存就把所有状态变量都改成了static。结果更糟了因为static变量在场景切换的时候不会重置导致第二次玩游戏的时候状态还是上一次的。后来我查了很多资料才明白问题出在Unity的场景加载机制上。默认情况下加载新场景会销毁当前场景的所有GameObject包括挂载在上面的脚本和变量。正确的做法是使用DontDestroyOnLoad。把管理状态的脚本挂在一个根物体上然后调用DontDestroyOnLoad(gameObject)这样这个物体在场景切换的时候就不会被销毁。但要注意这个物体不能重复创建否则会有多个实例。我的做法是在Awake里加一个判断private static GameManager instance; void Awake() { if (instance null) { instance this; DontDestroyOnLoad(gameObject); } else { Destroy(gameObject); } }这个模式叫单例模式是Unity里管理全局状态的标准做法。我建议所有做多场景游戏的朋友在项目一开始就把这个框架搭好不要等到出了问题再改因为改起来会牵一发而动全身。5. 测试反馈与迭代那些试玩者教我的事5.1 第一次测试所有人都不知道能点哪里第一次内部测试我找了五个同学来试玩。结果五个人里有四个在第一个场景就卡住了不知道要干什么。他们坐在座位上看着屏幕等了半分钟然后问我“然后呢”这个反馈让我意识到一个严重的问题我太熟悉自己的游戏了以至于忘记了玩家是第一次接触。我知道要点乘客、点车窗、点手机但玩家不知道。他们需要一些视觉暗示。我的解决方案是加了一个微弱的呼吸效果。所有可点击的热点在未被点击的时候会有一个非常缓慢的透明度变化从100%到80%再回到100%周期大概2秒。这个效果很微妙不会破坏沉浸感但足以让玩家的余光注意到“这个东西好像可以点”。加了呼吸效果之后第二次测试所有玩家都能在10秒内找到第一个可点击的对象。另一个改动是加了一个极简的新手引导。不是那种弹窗式的“点击这里”而是在游戏开始的时候用一行小字在屏幕底部显示“你坐下了。看看周围吧。”这句话既交代了状态又暗示了“看”这个动作。玩家看到这句话之后自然会去尝试点击周围的东西。5.2 第二次测试节奏太慢玩家在第三站就退出了第二次测试我找了另外五个人这次他们都能顺利开始但问题变成了节奏太慢。有两个人玩到第三站就退出了问他们为什么回答是“感觉没什么变化”“一直在看文字有点累”。这个反馈让我重新审视了信息密度的问题。我原本的设计是每一站两到三个事件每个事件大概三到五句话。但实际玩起来玩家在每一站停留的时间大概是两到三分钟其中大部分时间是在读文字。连续读三站之后确实会疲劳。我的调整方案是增加非文字类的反馈。具体来说我做了三件事。第一给每个事件加了一个简短的动画。比如“学生背单词”这个事件点击之后学生的Sprite会有一个翻书的动作两帧切换。“阿姨外放短视频”这个事件会有一个手机屏幕闪烁的效果。这些动画很简单但能让玩家在阅读文字之外有一个视觉上的“奖励”。第二缩短了单次事件的文本长度。原来一个事件可能有三到五句话我压缩到了一到两句。把更多的信息分散到多个事件里而不是集中在一个事件里。这样玩家每次点击都能快速得到反馈不会觉得“怎么还没完”。第三增加了“跳过”功能。虽然我一开始觉得“跳过”会破坏沉浸感但测试表明有些玩家就是想快速过一遍不想逐字阅读。所以我加了一个长按屏幕加速文字显示的功能。玩家如果不想等文字逐字出现可以长按跳过动画。这个功能加了之后退出率明显下降。5.3 第三次测试有人开始“二周目”这让我很意外第三次测试是最让我惊喜的一次。我找了十个玩家其中有三个人在通关之后主动重新开始玩了一遍。我问他们为什么他们说“想看看如果当时选了另一个选项会怎么样。”这个反馈让我意识到选择类事件的价值被低估了。我原本只设计了三个选择类事件而且都是很微小的选择比如“让座”还是“不让座”。但玩家对“选择”的敏感度远高于我的预期。他们会记住自己做了什么选择并且好奇另一个选择会导致什么结果。所以我后来做了一件事给每个选择类事件都加了“后续回响”。比如你在第二站选择了“让座”到了第五站那个被你让座的人会再次出现并且对你点头微笑。如果你选择了“不让座”到了第五站那个人就不会出现但你会看到另一个乘客在同样的位置站着。这种“回响”不需要很复杂只需要在后续的站点里加一个条件判断根据之前的选择决定显示哪个事件。这个设计让游戏的重玩价值提升了很多。虽然整体流程还是八站但不同的选择会导致不同的事件组合玩家会想要“再坐一次”看看有什么不同。6. 如果你也想做一个这些经验可以直接拿走6.1 从“最小可玩切片”开始不要一上来就做完整版我见过太多非科班的朋友一上来就想做一个“完整的游戏”。结果做了三个月连第一个关卡都没做完然后就放弃了。我的建议是先做一个“最小可玩切片”。什么叫最小可玩切片就是一个场景、一个交互、一个反馈。比如我的项目最小切片就是一个车厢背景、一个可点击的乘客、点击之后显示一段文字。就这三样东西。我花了大概两天时间把这个切片做出来跑通了然后才在这个基础上加第二个乘客、第二个场景、第二个事件。这样做的好处是你永远有一个能跑的东西。哪怕后面加了很多功能核心的“点击-反馈”循环始终是通的。你不会因为某个复杂功能卡住而整个项目停滞。而且当你看到那个最小切片跑起来的时候你会获得巨大的成就感这种成就感是支撑你继续做下去的动力。6.2 文本量比你想象的大三倍提前做好内容规划我一开始觉得八站每站三个事件每个事件三句话总共也就七十二句话不多。但实际写起来我发现每一句话都要反复改。第一版写出来读一遍觉得太生硬改一版读一遍觉得太啰嗦再改一版读一遍觉得没有画面感。一句话改五遍是常态。而且除了事件文本还有站名、提示语、UI文字、报站音效的文本。这些加起来实际的文本量是我最初预估的三倍。所以我建议在开始写代码之前先把所有文本写出来。用Excel或者Notion列一个表每一行是一个事件每一列是站名、事件类型、触发条件、文本内容。写完之后再开始做技术实现。这样你不会写着写着发现“没内容可做了”。6.3 音效和背景音乐是性价比最高的氛围工具如果你只能在一个方面投入额外的时间我建议是音效。视觉上你画得再简陋只要音效对了氛围就对了。公交车的发动机声、车门的气动声、报站的电子音、乘客的脚步声、刷卡机的滴滴声——这些声音叠在一起玩家立刻就能“进入”那个场景。背景音乐反而要谨慎。我一开始加了一段很舒缓的钢琴曲结果测试的时候所有人都说“太吵了”“像在咖啡厅”。后来我把背景音乐去掉了只保留环境音效反而效果更好。因为公交车的真实体验就是没有背景音乐的只有各种环境噪音。所以我的建议是环境音效拉满背景音乐能省则省。6.4 发布平台的选择itch.io比想象中友好做完了之后我把它发布在了itch.io上。这是一个独立游戏发布平台对新手非常友好。不需要审核不需要付费上传一个WebGL版本就能直接玩。而且itch.io的社区氛围很好很多人会给你留言反馈甚至有人会帮你写评测。WebGL版本的好处是跨平台。PC、Mac、手机、平板只要有浏览器就能玩。虽然性能不如原生版本但对于我这种2D叙事游戏来说完全够用。导出WebGL的时候要注意两点一是压缩格式我选的是Brotli压缩率高加载快二是内存限制WebGL默认的内存上限是256MB如果超了会崩溃。我的项目因为都是2D素材内存占用很小所以没遇到这个问题。但如果你要做3D的就要注意控制纹理大小。7. 做完这个项目之后我对“新媒体游戏”的一些真实想法这个项目做完之后我最大的感受是新媒体背景的人做游戏优势不在技术在“视角”。科班出身的人做游戏往往从“机制”出发想的是“我要做一个什么玩法”。但新媒体背景的人习惯从“体验”出发想的是“我要让玩家感受到什么”。这两种思路没有高下之分但后者在做叙事类、氛围类、情感类内容的时候确实更有优势。公交这个场景之所以能成立不是因为它有什么复杂的玩法而是因为它是一个每个人都经历过、但很少被认真注视的日常空间。你在公交车上看到的那些碎片——打瞌睡的人、外放短视频的人、背单词的人、吵架的情侣——它们本身没有戏剧性但当你把它们放在一个封闭的、移动的、临时的空间里它们就产生了一种微妙的张力。这种张力不需要复杂的机制来支撑只需要让玩家停下来看一看。如果你也是新媒体背景也想做点互动内容我的建议是不要被“游戏”这个词吓到。你不需要做3A大作不需要懂什么渲染管线、物理引擎、网络同步。你只需要找到一个你熟悉的场景把它拆解成可交互的碎片然后用最简单的工具把它们拼起来。Unity也好Godot也好甚至Twine、Ink、Ren‘Py这些专门做叙事游戏的工具也好选一个你能上手的先做一个最小切片出来。做完之后你会发现“做游戏”这件事门槛没有你想象的那么高。真正难的是找到一个值得被做成游戏的场景以及一种值得被玩家体验的视角。而这两样东西恰恰是新媒体训练最擅长的。最后分享一个我在测试期间收到的最喜欢的反馈。有一个玩家在通关之后留言说“我每天坐公交上下班从来没注意过车上的人。玩了这个之后第二天我坐车的时候真的抬头看了看周围的人。”这条留言让我觉得这个项目做值了。
返回列表