制作中国版模组SDK界面¶
这一页讲中国版模组SDK里的自定义UI工作流:先用旧版MC Studio界面编辑器或手写JSON准备界面,再用Python把界面注册到游戏里,最后通过UI API动态改控件状态。它不适用于国际版@minecraft/server-ui,也不等同于国际版资源包覆盖原版JSON UI。
先记住三件事¶
开始之前,先把最容易出错的三件事记牢:
- JSON文件名、界面命名空间和对应的Python文件名最好保持一致。
- 界面贴图优先使用PNG,并只用字母、数字和下划线命名。
- UI布局只是静态外观,真正的交互逻辑要写在继承
ScreenNode的Python类里。
如果一开始就把资源名、命名空间和脚本类路径弄乱,后面排查会很痛苦。
第一步:准备界面资源¶
中国版旧版做法,是先把按钮、准心、面板背景等图片导入资源管理器,再新建界面文件。常见资源会进入资源包的ui/与贴图目录中;保存界面后,编辑器会导出可直接运行的JSON界面文件。
如果是手写或接手旧项目,至少要先确认:
- 贴图是否真的存在;
- 资源名是否只含字母、数字和下划线;
- JSON文件里的命名空间是否与脚本注册时一致。
第二步:先搭结构,再调细节¶
做中国版UI时,通常先把结构搭出来,再处理样式。一个常见顺序是:
- 创建画布。
- 创建若干面板作为分组容器。
- 往面板里放图片、按钮、文本、滚动列表或网格。
- 最后再调锚点、位移、尺寸和层级。
旧版资料反复强调,面板更像“容器”,方便后续整体移动和批量隐藏;如果一上来就把所有控件直接挂在根节点下,后面改层级和适配会越来越乱。
第三步:理解锚点、位移、尺寸和层级¶
中国版旧版UI,最重要的布局概念就是四项:
- 锚点:决定子控件与父控件的哪个位置对齐。
- 位移:在锚点基础上继续偏移。
- 尺寸:决定控件宽高。
- 层级:决定遮挡顺序。
旧版界面编辑器把位移和尺寸都写成%+Px语义:百分比部分按父控件尺寸计算,像素部分再叠加固定偏移。简单界面常直接用像素,只有在需要跟随父控件尺寸变化时才大量使用百分比。
如果界面出现“按钮被图片盖住”这类问题,先查层级,不要先怀疑脚本。
第四步:需要适配时,留意基类画布¶
旧版,继承common.base_screen的画布会引入额外根节点路径,用来处理安全区域和异形屏适配。这样做的副作用是:控件在脚本里访问时,路径可能不再只是/panel/text这种相对短路径,而要额外拼接一段基础路径。
所以,接手旧项目时如果发现:
- JSON明明有这个控件;
- 界面也确实显示出来了;
- 但
SetVisible、SetText之类接口就是不生效;
优先检查这个界面是不是用了基类画布和安全区域包装。
第五步:把JSON接到Python¶
中国版模组SDK的自定义UI通常在客户端系统里完成注册和创建:
import mod.client.extraClientApi as clientApi
class MyClientSystem(clientApi.GetClientSystemCls()):
def __init__(self, namespace, systemName):
super().__init__(namespace, systemName)
clientApi.RegisterUI("myMod", "fpsBattle", FpsBattleScreen, "fpsBattle.main")
def ShowHud(self):
return clientApi.CreateUI("myMod", "fpsBattle", {"isHud": 1})
对应的UI类需要继承ScreenNode。创建成功后,就可以通过GetUI拿到实例,再调用界面接口改控件状态。
第六步:只把“会变化的内容”放到脚本里¶
旧版官方教程里常见的分工是:
- JSON负责初始布局和默认外观;
- Python负责显示、隐藏、切换文本、响应点击和更新状态。
例如开镜按钮按下后隐藏准心、显示瞄准镜,或者点击按钮后切换弹匣图标,这些都更适合在脚本里做。这样布局与逻辑分离,后面替换贴图或微调位置时不会牵一发而动全身。
第七步:需要挂到原生界面时¶
如果目标不是单独弹出一个自定义界面,而是把自己的控件附加到背包、箱子或熔炉等原生界面上,旧版中国版资料建议改用NativeScreenManager与CustomUIControlProxy这一套框架。
这种做法的思路是:
- 先选定一个允许附加的原生界面枚举;
- 用
RegisterCustomControl把自定义控件注册到该原生界面; - 继承
CustomUIControlProxy,在OnCreate里拿到BaseUIControl根节点并写初始化逻辑; - 在
OnDestroy和OnTick里处理清理或逐帧更新。
它更适合做“在原生界面上补一块额外信息区、按钮区或提示区”,而不是重写整套原生界面逻辑。
常见问题¶
界面创建不出来¶
先检查以下四项:
RegisterUI里的命名空间、键和定义路径是否与资源文件一致;- JSON文件名、命名空间、Python类路径是否对应;
- 客户端系统是否真的执行到了注册代码;
- 资源包里的UI文件是否已经导出到正确目录。
控件接口不生效¶
先确认控件路径是否正确;如果界面继承了common.base_screen,再检查是否遗漏了安全区域带来的基础路径。
按钮层级不对¶
先调层级或控件树顺序。旧版资料说明,自动层级调整与手动层级调整混用时,最容易出现“界面看起来对,运行时遮挡顺序却不对”的问题。