Kzeroko KTM2

变身客户端表现与兼容

粒化遮蔽驱动的模型切换、第一人称手臂、摄像机、输入、HUD、纹理与客户端扩展。

更新于 2026/9/30 12 分钟阅读

变身表现是叠加在服务端组件之上的客户端状态机。它以 Particlize 遮蔽协调可见形态,同时输入、碰撞尺寸和原生物种模拟各自保留权限归属。

它做什么

ClientMorphRenderManager 将玩家解析为当前可见的未生成形态。实体分发器在宿主渲染调用中选择该形态渲染器。玩家骨架形态还会打开 HumanoidMorphRenderScope,借用宿主动画姿态。这些类型位于客户端或内部实现包,并非公开客户端门面。

运行时模型

模型切换与渲染顺序

组件的半程判定并不直接决定绘制哪个模型。MorphPresentationController 等待变身脉冲达到 COVERED 或 COMPOSING,再显示进入形态或隐藏退出形态。若没有脉冲,稳定的 ACTIVE 显示形态,稳定的 NONE 清空表现。即使权威组件已清空,只要遮蔽仍待完成,退出表现也可能继续保留。

分发器先解析表现,再包装 Particlize 和着色器捕获。详细表面 Particlize 优先于 ShaderFX 捕获。阴影通道遵循 Particlize 抑制,并绕过普通捕获包装。AcceleratedRendering 管线选择具有作用域,并在 finally 恢复;这不表示所有第三方渲染层都支持所有特效。

表现更新复制宿主状态,但可保留原生形态旋转。对于既非玩家骨架、也未注册形态 ticker 的形态,回退动画栈每个宿主年龄 tick 最多推进一次。已注册 ticker 负责物种推进,渲染不应再补一次 tick。

输入与 HUD

无界面打开时,激活的模块化形态接管攻击和使用输入。主能力按下后每 2 个客户端 tick 重复,副能力只发送按下和释放,不进入该重复循环。最终仍由服务端间隔与冷却决定。打开界面或离开可接受状态会释放已按住能力,加入时清空记忆输入,避免上次连接留下按键锁定。

过渡及模块化形态阻止攻击、使用和挖掘;激活的玩家骨架保留玩家操作。进入非玩家控制阶段会取消正在进行的人类武器前摇。激活玩家骨架冲刺时按潜行会取消冲刺。

特殊移动通常要求在 400 ms 内双击跳跃。PRESS 处理器首次按下即可激活,但停用仍进入双击分支。只有处理器允许时客户端才预测,随后发送权威请求。打开界面会抑制跳跃和潜行;移动字节读取玩家移动轴,本控制器没有为它们单独检查界面。

ModernUI HUD 在无玩家或世界、打开界面、HUD 关闭或没有变身时隐藏。玩家骨架采用不含能力卡片的紧凑显示。主能力固定显示连段状态,不显示主能力冷却;副能力显示经过显示解析的冷却及就绪条。卡片字面标签为 LMB、RMB,而实际输入遵循配置的攻击和使用绑定。

无限形态的主条显示过渡进度,激活时保持满格。限时形态显示剩余时长比例,只在激活时递减。HUD 按捕获的单调时钟以每秒 20 tick 外推,不修改服务端冷却。更新合并后再投递 UI 线程;漂移容差为 0.002 进度与当前速率下 0.1 秒两者中的较大值。

约定

纹理与附加层

MorphSkinRegistry 在客户端资源重载时发现 textures/morphs 下的 PNG。候选路径及皮肤优先级见变身数据。若变体提供者接管形态纹理,通用覆盖关闭。

MorphTextureOverrideScope 仅重映射渲染器原始纹理 ID,关闭时恢复先前作用域。其他附加层纹理保持不变,除非它们恰好使用同一个 ID。RenderLayer mixin 覆盖实体 solid、cutout、no-cull、no-cull Z-offset、translucent、translucent-cull、translucent-emissive、smooth-cutout、no-outline 和 alpha 构造入口,不拦截任意渲染器专用纹理通道。

HUD 能力翻译先查 morph_ability.<namespace>.<ability-path>.<entity-namespace>.<entity-path>,再查通用能力键,最后使用原始能力路径。翻译键中的斜杠改为点,翻译通过 language_assemble 添加。

第一人称玩家骨架

Player Animator 第一人称通道对玩家骨架表现保留宿主玩家渲染器,再替换对应形态手臂。完全遮蔽的切换阶段会隐藏手部。当 Player Animator 的 THIRD_PERSON_MODEL 模式负责手部时,Punchy 让出绘制,避免重复。

MorphFirstPersonArmRenderer 可通过 GeoHumanNpcRenderer.renderFirstPersonArm 支持 BaseNpcEntity,或使用能通过双足、命名子节点桥接找到所需手臂的生物渲染器。若被标记实体的渲染器不受支持,或缺少手臂,就可能无法绘制替代手臂;仅加入 morph_player_rigs 并不充分。

变换由调用者已计算姿态的手臂提供。原版模型替换会临时重置形态手臂变换、设为可见、渲染,再在 finally 恢复两项属性。Gecko NPC 使用专用手臂路径。普通人形玩家手臂路径另见人形运行时。

Player Animator 对齐将模型空间偏移“原版姿态眼高减去平滑摄像机眼高”。基准为游泳、鞘翅飞行、旋转攻击 0.4,蹲伏 1.27,其余 1.62。仅本地第一人称摄像机聚焦该玩家时应用,忽略不超过 0.0001 的偏移。它使手部对齐变化中的摄像机,不改变玩家碰撞箱。

摄像机与视角

设置 / 值默认约定
morphPerspectiveModeAUTO_THIRD_PERSON本地配置,morph 分类。
AUTO_THIRD_PERSON已选从 NONE 进入时,非玩家骨架切换到后置第三人称,并记住原视角。
KEEP未选不自动切换视角。

退出到 NONE 或断线时,只有当前视角仍等于控制器施加的视角,才恢复旧视角;手动切换会被尊重。在已有形态之间切换不会重新触发最初进入事件。

MorphCameraSubject 优先使用观察者自身已接管尺寸的形态,否则使用其所乘玩家的受支持载运形态。提供者只在第三人称采样。MorphCameraPose 包含后退距离、横向位移、竖向位移和俯仰偏移;record 本身不验证数值。

后退距离进入原版碰撞裁剪,横向和竖向偏移在之后应用,不经过同一次裁剪;最终 pitch 限制为 −90…90。过场摄像机混合发生在变身摄像机调整之后,因此提供者不能假定独占摄像机。

客户端扩展钩子

以下是客户端实现注册表,不是 api.client 门面,仅应在客户端初始化阶段注册。

注册表 / 回调注册键行为
MorphClientAbilityPreviewRegistry / handle(player, morph, form, slot, action)精确实体类型重复抛出异常,回调运行时失败会记录并移除预览。内置监守者激活以状态 4 表示近战,62 表示音爆蓄力。
MorphClientFormSkillPreviewRegistry / handle(player, morph, form, actionId, inputAction)实体类型 + 动作 ID重复抛出异常,失败回调按该组合移除。
MorphCameraRegistry / sample(player, morph, form, tickDelta)精确实体类型重复抛出异常;null 采样停用该提供者,采样失败移除;更换提供者会重置前一个。
MorphPassengerPoseRegistry / apply(host, form, passenger, seatIndex, matrices, tickDelta)精确实体类型要求激活载运者、乘坐处理器和真实乘客索引;重复抛出异常,失败移除姿态处理器。

能力和形态技能预览数据包发送给跟踪玩家及宿主,在客户端线程上仅对仍激活的形态执行。它们携带宿主实体 ID 和槽位、动作信息,不携带形态修订号;快速切换形态后,不能把预览包视为原会话仍存在的证明。

MorphCameraRegistry.reset 清除当前提供者并调用 reset 钩子,没有通用异常保护。reset 即使在部分初始化或采样失败后也应安全。乘客姿态钩子返回或失败时,应恢复自己负责的临时矩阵变化。

兼容边界

集成实际桥接
Player Animator / Better Combat宿主姿态及手持物品变换驱动兼容玩家骨架;无专属 ticker 时,回退动画每宿主 tick 推进一次。
Better Animations可选反射倾斜与挤压桥接,冲刺或潜行时跳过,鞘翅飞行时归零;反射或类型失败在本进程中禁用桥接。
Crawl为玩家骨架反射读取爬行状态,并按宿主渲染器应用爬行朝向。解析失败则无集成,后续调用失败则禁用。
Presence Footsteps非玩家骨架只有在引擎启用该形态,且为精确实体 ID 编写了运动定义时,才使用形态步声生成器;也只有存在此生成器时才抑制原版步声。
Punchy为受支持玩家骨架替换手臂,共用 Particlize 遮蔽,避免重复绘制 Player Animator 负责的手部。
Saints Dragons仅模组存在时加载。客户端启动捕获链接或运行时错误并记录;原生物种注册与模拟还需要公共侧桥接。

声音来源遵循 usesMorphDimensions。调用原生脚步、受伤、死亡或环境声音前先同步形态声音状态。玩家骨架脚步保留普通玩家路径,缺失 Presence Footsteps 形态定义不应抑制原生回退。

身体相对视觉使用 EntityVisualBounds:当前碰撞箱尺寸与当前姿态眼高。几何键包含按 10000 量化的尺寸、眼高,以及姿态、变身修订号和尺寸归属标志。锚点在选定脚部位置上增加当前高度的比例偏移。这是边界约定,不是采样渲染网格,也不保证与脉冲切换的模型几何逐帧完全一致。

扩展方式

分别处理服务端阶段、客户端可见表现、碰撞尺寸与原生旋转。渲染使用表现解析器,权限使用组件状态,空间附着使用实时边界,物种动画使用已注册原生 ticker。不要把同一阶段条件复制到四条路径。

新的玩家骨架渲染器需提供兼容身体和手臂名称,以及第一人称提取。新的模块化物种可增加预览、摄像机和乘客姿态钩子,无需替换宿主输入或世界实体。原生 tick 归属应配合 detach 清理,并恢复全部作用域纹理、矩阵与渲染管线状态。

UI 更新属于 ModernUI 的 UI 线程,游戏输入采样保留在客户端 tick 线程。不要从异步 UI 动画回调读取或修改实时世界。渲染注册表与失败集成标志的生命周期不同,应测试资源重载和重连。

FirstPersonArmor在Player Animator筛选第一人称特征层之后,恢复已注册的护甲特征层。渲染器随后在原生特征层阶段调用它,沿用Player Animator对每层的矩阵处理。胸甲交回原有装备槽绘制调用,因此原版材质、Fabric回调与GeckoLib模型提供器继续使用各自的姿态复制和绘制流程。这一阶段跳过头盔、护腿与靴子,袖部可见性跟随玩家模型中显示的手臂。

这层兼容只调整可见性。原生装备槽选择之后重新套用仅含手臂的遮罩;双足模型绘制结束或失败后恢复原有可见性。GeckoLib保留自身骨骼变换、缓冲区与渲染层。GeoArmorSleeveGeometryMixin拦截所选手臂分支之外的方块,同时允许遍历作为手臂父节点的躯干。普通玩家绘制会重新应用装备槽可见性,变形身体继续遵守自身装备规则。

待机护甲由Punchy内建袖部流程负责。本兼容不替换该流程,也不额外绘制一次待机护甲。已退役的矩阵回放和直接护甲绘制调用器不再打包。人形皮肤替换保留原生模型遍历,参见人形运行时。

游戏内验收须覆盖待机与攻击、左右手、纤细与标准玩家、原版染色与纹饰护甲、Fabric自定义护甲、GeckoLib袖部、光影,以及返回第三人称。自动检查覆盖特征层选择、可见性恢复和打包后的注入目标,不能据此认定画面已经对齐。

验证

使用专用服务端、所有者和观察者。分别在正常、延迟、缺失脉冲时进入和退出,检查旧形态在切换前仍受遮蔽,组件尺寸变化也正确。对阴影通道、详细 Particlize、ShaderFX 和界面预览重复检查。

测试第一、第三人称,手动视角切换、载运摄像机、摄像机遮挡与过场叠加。玩家骨架需在 Punchy 和 Player Animator 下检查双手、眼高变化及不受支持手臂几何。

持续主能力、点按和持续副能力、按住时打开界面、更换按键、重连;对比客户端输入频率与服务端接受结果。单独验证 PRESS 移动形态的进入和双击退出。

在进度为空或满格、不同刷新率、限时到期、长翻译和紧凑玩家骨架模式下检查 HUD。纹理覆盖分别测试独立附加层纹理与故意共用基础 ID 的附加层;比较有无专用定义的 Presence Footsteps 形态。

相关页面