傅可心 / greenbread.cn
← 返回首页

个人项目 · UNITY CLIENT SYSTEMS

嘴遁大师

从零独立搭建一套 Unity 2D 游戏客户端:将内容数据转换为可运行关卡, 管理玩家、输入、HUD、关卡、复活与结算的生命周期,并完成网状解锁、存档迁移和微信小游戏平台接入。 核心关注点不是玩法概念本身,而是如何让几十个关卡持续接入同一套稳定、可维护的运行框架。

项目类型
2D 平台 · 独立项目
平台
微信小游戏 · Unity WebGL
引擎
Unity 6 · URP
状态
2026 · 备案中
嘴遁大师项目主画面

CASE SUMMARY

从内容数据,
到稳定运行的客户端闭环。

关卡运行时数据 → 平台 / 机关 / 分支
场景生命周期常驻玩法壳 / Additive Scene
状态与存档网状解锁 / JSON 迁移
平台抽象本地 / 微信双实现
01

客户端运行链路

从入口校验到进度落盘都由同一条客户端链路管理:读取状态 → 进关门控 → 加载玩法壳与关卡 → 运行数据节点 → 结算 / 复活 → 写入存档并重新计算解锁。 自定义关卡复用运行时,但通过独立入口隔离正式经济与进度。

环节 做的事 要解决的问题
选关 按联系人聚合关卡,只展示已满足出现条件的条目;进入当前可玩关,或从详情重玩已通关关卡。 关卡是网状依赖,不能做成一张平铺列表。
进关 校验解锁与体力,用常驻遮罩盖住切换,再加载玩法壳并叠加关卡场景。 每关复制一份玩家与 HUD 无法维护;切换过程不能露出半加载状态。
关卡推进 对话节点驱动平台出现、文字显现、选项分支和机关组启用;角色在平台上移动以推进节点。 玩法几何和内容数据必须是同一套,改对话不能再手改碰撞。
失败与复活 死亡后按关卡难度换算花费,确认后回满生命继续本局,每局限一次。 失败处理要接进结算,而不是另写一条重开流程。
结算与解锁 按表现评级、发放货币、写入通关记录,再扫描全部关卡数据,把新满足条件的关标为可出现。 一次通关可能点亮多个联系人下的关,不能只维护「下一关」指针。
自定义关卡 编辑器产出与正式关相同的对话节点,运行时直接游玩;分享走平台接口,不写入正式进度。 内容长度运行时才知道,且平台侧必须能在编辑器里脱离 SDK 验证。
02

客户端系统详解

以下四个模块按「运行时数据、生命周期、持久化状态、平台边界」展开,重点说明具体问题如何定位和解决。

一、数据驱动的关卡运行时

Runtime

问题:关卡几何由对话内容决定。 平台尺寸、落脚点、机关和文字显现必须跟节点走; 传送、受击和复活会产生位移,不能把这类位移当成玩家「走完了这一句」。

做法:一条对话节点对应一块平台物体,文字、碰撞、锚点和可选机关组挂在同一处。 文字按角色在平台上的水平行程逐步显现;超过阈值的位移视为传送,不计入行程。 推进器维护平台对象池,按屏幕比例槽位排版,节点完成后锁定输入、延迟再切到下一节点。 角色控制按不规则平台单独调:地面与空中加速度分开、单击跳与长按高跳、边缘保护只对平台层采样,低矮障碍可走上。

结果:正式关用手摆固定尺寸,手感可逐关调; 自定义关卡因文本长度未知,另做按实际高度累加的布局。两套排版分开,避免互相改坏。

  • 数据驱动几何:改对话节点就能改平台和机关,不必再手改一套碰撞。
  • 输入与表现分离:行走才推进文字,系统传送不影响节点进度。
  • 能力开关:跳跃等能力由关卡模式打开或关闭,正式关默认行为不变。

为什么不让所有关卡都自适应尺寸?

正式关要保证手感,平台尺寸和落点必须可预估。自适应适合文本长度不可预知的情况。为了复用硬合成一套,两边都会变难调。

2D 手感上具体调了什么?

不是套一份通用控制器就结束。平台是圆角气泡,要单独做边缘保护和上台阶;否则角色会在边缘滑落,或被平台上的道具误判为离地。

二、常驻玩法壳与场景生命周期

Lifecycle

问题:每关都需要角色、输入、HUD 和结算。 如果每个关卡场景复制一份壳,改一处流程就要改所有场景; 叠加加载时,壳上的流程脚本也拿不到关卡里尚未就绪的对象。

做法:进关只做门控:校验解锁、消耗体力、记录当前关,再交给常驻过渡遮罩。 遮罩盖住之后加载玩法壳,关卡场景再叠加进来。 结算与复活挂在壳上,等关卡场景加载完成再绑定引用。 自定义关卡不走正式进关,避免误写进度。

结果:改 HUD、复活和输入只动玩法壳; 关卡场景只带数据和摆放内容。新增一关不必复制壳。

  • 壳与内容分离:常驻的是流程,叠加的是关卡数据。
  • 加载时序:先遮罩,再切场景,避免半加载露给玩家。
  • 跨场景通信:流程脚本等叠加完成再接线;少量跨场景通知用静态事件,不在运行时查找对象。

为什么不把玩家直接放进每个关卡场景?

关卡数量上去之后,复活、体力、输入和 HUD 会变成多份拷贝。壳只应有一份,关卡只应提供数据和摆放。

叠加加载最容易出什么问题?

壳先就绪、关卡后到,直接取引用会空。要按场景加载事件分步绑定,成功后取消订阅,避免重复接线。

三、进度状态、解锁图与存档迁移

State

问题:关卡挂在不同联系人下,解锁要能跨联系人、卡评级、卡时间。 主界面还要按「当前能接触到什么」过滤,而不是把整张图摊开。

做法:联系人与关卡都是 ScriptableObject。 解锁条件按 AND 组合,支持立即、次日和延迟小时。 「已出现」和「可进入」分开:付费关可以先出现在列表里,购买后才能进。 通关后扫描全部关卡数据,把新满足条件的条目标为已出现。 复活花费和首通奖励由全局经济配置按难度换算,不在关卡上手填价格。

结果:加关主要是填数据和摆场景; 主界面未读数量等于已出现但未通关的关卡数,进度用 JSON 本地持久化,并带字段迁移。

  • 状态拆分:出现、购买、可进入是三层,避免把付费和剧情锁写死在同一字段。
  • 全图扫描:一次结算可以点亮多个联系人下的关,不维护硬编码的下一关指针。
  • 排序约定:解锁时间只在真正解锁时写入,避免开局关和后续关抢同一排序键。

为什么解锁条件要做成数据,而不是在结算里写 if?

关卡会继续加,依赖也会跨联系人。写在结算函数里,每加一条就要改代码。条件落在数据上,结算只负责扫描和写入。

进度存在本地,后面加字段怎么办?

存档带迁移。例如后来才有的人生阶段推进,会对已经解锁的过渡关补写,避免旧存档永远停在上一阶段。

四、微信平台能力抽象

Platform

问题:目标平台是微信小游戏。 SDK 在编辑器里不可用,业务逻辑又不能到处写条件编译; 用户生成内容一旦发出去就难以撤回,检查必须发生在对外分发之前。

做法:自定义关卡复用正式关的对话节点,运行时不转换格式。 分享业务只依赖一组接口:存储、内容检查、拉起卡片。 编辑器使用本地实现,微信实现只编进 WebGL,启动时替换。 流程固定为检查、落库、再拉卡片;启动参数只带分享标识,不带正文。 从后台回到前台时按平台生命周期领取,不假定会重新跑一遍启动逻辑。

结果:同一套业务在编辑器里就能验证领取、过期和失败回显; 真机只换实现。内容检查的最终判定放在云函数,不依赖客户端拦截。

  • 接口隔离:业务不直接调微信 API,平台差异留在实现层。
  • 分发边界:对外只传标识,正文从服务端按身份领取,才能做名额和过期。
  • 热启动:分享入口按 OnShow 处理,玩家若仍在关卡内,回到主界面再领取。

为什么不在业务代码里直接写微信调用?

编辑器编不过、也测不了。抽一层之后,日常开发走本地实现,出包再换微信实现,调用方不用改。

内容检查为什么不能只做在客户端?

客户端检查可以被绕过。对外分发的权威判定必须在云函数完成,客户端只负责展示失败原因。

03

项目画面

关卡选择界面
zuidun-1.jpg关卡选择 / 联系人列表
关卡选择:按联系人聚合,只展示当前可接触的条目。
联系人详情与关卡归类
zuidun-4.jpg联系人详情 / 关卡列表
联系人详情:该联系人下的关卡归类,已通关可重玩,未解锁显示条件。
关卡内玩法
zuidun-2.jpg关卡内 / 平台推进
关卡内:对话节点同时驱动平台、文字显现与机关。
自定义关卡
zuidun-3.jpg自定义关卡编辑 / 试玩
自定义关卡:同一套对话节点,编辑后直接进入游玩。
04

工程与排障

个人项目同样要处理加载时序、存档语义和平台差异。下面是几处关键判断,而不是功能清单。

问题 定位过程 处理
叠加加载后流程脚本取不到关卡对象 玩法壳先加载完成,关卡场景后到。在第一次场景回调里取引用,得到的是空。 按场景加载事件分步绑定,关卡未到就再等一次;绑定成功后取消订阅,避免重复接线。
通关后关卡列表排序错乱 开局关和刚解锁的关写了同一秒的时间戳,排序键打平,起始条目被顶到新条目之上。 通关只写完成记录,不回写解锁时间;开局关的解锁时间保持为空值,排序语义才稳定。
关卡场景里扫不到配置资产 按类型全量查找只能找到已经被引用进内存的 ScriptableObject。主界面拖了列表,关卡场景没有。 改成显式登记表,所有联系人数据挂在同一份资产上,解锁扫描不再依赖当前场景引用了什么。
小游戏里运行时切方向无效 编辑器里改 Screen.orientation 可以,真机小游戏不生效,方向由导出配置决定。 不把转屏当成小游戏上的可靠能力;自定义关卡按竖屏做,正式关的横屏路径只用于编辑器和原生包。
05

客户端能力结论

这个项目证明了什么

  • 能独立完成 Unity 客户端全链路:运行时、角色控制、场景切换、结算、存档与平台接入,并处理模块间状态一致性。
  • 能用常驻玩法壳 + 叠加关卡划分生命周期,让新增关卡只提供数据和内容,不复制玩家、HUD 与流程逻辑。
  • 能把变化隔离在正确边界:解锁规则落到数据,旧存档通过迁移兼容,平台差异通过接口替换,编辑器与真机共享业务层。