☰
MCreator 方块状态列表(Block States List)使用与实现原理详解
2026/10/16 5:38:00 网站建设 项目流程
  • 低代码
  • 代码生成
  • 桌面应用
  • 游戏开发

【免费下载链接】MCreator

MCreator is an open-source software used to make Minecraft Java Edition mods, Minecraft Bedrock Edition Add-Ons, resource packs, and data packs using an intuitive easy-to-learn interface or with an integrated code editor. It is used worldwide by Minecraft players, aspiring mod developers, for education, online classes, and STEM workshops.

项目地址:https://gitcode.com/gh_mirrors/mc/MCreator
点击查看免费下载

MCreator 的方块编辑器提供了“状态列表”(states list)系统,允许开发者为自定义方块定义随方块状态属性(block state property)取值而变化的模型与碰撞体。本文基于 MCreator 帮助文档block/states_list条目,结合Block元素模型、状态属性工具类与 NeoForge 生成模板的源码,完整讲解该系统的核心规则(属性一致性约束、缺失组合自动补全、旋转组合自动生成)、variants 与 multipart 两种导出格式的差别,以及属性数量上限等工程限制,帮助你在 MCreator 中正确配置可交互、可旋转、状态感知的自定义方块。

状态列表在 MCreator 中的位置与作用

状态列表是方块编辑器“状态”页签中的核心控件,帮助文档条目为 states_list.md(德文版,英文默认版位于 default/block/states_list.md)。在源码中,该帮助入口通过 BlockGUI.java 中的HelpUtils.wrapWithHelpButton(this.withEntry("block/states_list"), ...)挂载到界面上,与旁边的“状态格式”(variants / multipart)下拉框共同组成状态编辑区域。

这个列表为当前方块定义“方块状态及其条件”:每一行(StateEntry)包含一组状态属性取值(条件)与该状态对应的模型(Normal 或 Custom JSON/OBJ 模型,参见 state_model.md)、纹理与可选的自定义包围盒。使用该系统,可以创建“外观随状态属性取值而变化”的方块,例如随生长阶段切换模型、随朝向显示不同贴图的门或面板类方块。

核心规则一:variants 格式下属性必须“全有或全无”

帮助文档明确指出:如果某个方块状态属性被用在某条状态条件中,那么它必须出现在所有状态条件中。也就是说,在默认的 variants 导出格式下,所有状态条目必须使用同一组属性,构成完整的组合空间。

这条约束在代码层面有两处直接体现:

  • 界面校验与组合计算都假定“所有状态使用同一属性集合”。Block.java 的getStateCombinations()方法中注释写明all state maps use all properties as UI validation ensures this,并直接取第一条状态的属性集合作为全集:
    // collect all used properties (all state maps use all properties as UI validation ensures this) Set<PropertyData<?>> usedProperties = states.getFirst().stateMap.keySet();
  • 生成blockstatesJSON 时,模板对每个组合都输出完整的属性谓词(见下文 block_states.json.ftl 的variantPredicate拼接逻辑),因此缺属性的条目无法在 variants 格式下表达。

multipart 格式是例外。文档同时说明:该限制不适用于“多部件模型定义”(multipart model)。在 multipart 格式下,每个状态条目是一个独立的模型部件(part),部件条件可以使用属性的任意子集;空条件的部件始终渲染。详见 multipart_model.md。对应的源码差异在 Block.java 的getPropertiesUsedInStates()中:multipart 各部件可以使用不同属性子集,因此这里需要对所有状态求属性并集;而 variants 模式下只需单条目的属性集合即可。

核心规则二:缺失的属性组合自动用默认状态填充

文档写道:“Missing combinations of properties will be autofilled for you with the default block state.”(缺失的属性组合会自动用默认方块状态填充。)这一行为由 Block.getStateCombinations() 实现,其算法为:

  1. 以用户定义的状态列表为起点:retval = new ArrayList<>(states);
  2. 对每条用到的属性,通过BlockStatePropertyUtils.getPossiblePropertyValues(prop)枚举其全部可能取值;
  3. 用ListUtils.cartesianProduct(valueMap)生成所有属性的笛卡尔积,得到完整组合空间;
  4. 移除用户已定义的组合,将剩余组合补全为新的StateEntry,且renderType = -1(注释:use the default model,即使用默认模型);
  5. 返回补全后的列表。

这意味着你不需要为每个状态组合手写一行——比如定义了growing=true/false两个状态,若还有lit=true/false,那么growing=false,lit=true这类未定义组合会自动回落到方块默认模型,保证blockstates文件中所有组合都有合法映射,避免客户端加载时出现“未知状态组合”的警告。

核心规则三:启用旋转后自动生成全部旋转状态组合

文档还指出:“If block rotation is enabled, MCreator will automatically generate all the necessary state combinations to handle rotations.”(启用方块旋转后,MCreator 会自动生成处理旋转所需的全部状态组合。)

方块旋转由独立的 rotation_mode.md 帮助条目描述,共 6 种模式:无旋转、Y 轴旋转(S/W/N/E,按玩家朝向)、六向旋转(D/U/N/S/W/E,按玩家朝向)、按点击面旋转的 Y 轴/六向模式、原木式轴旋转(X/Y/Z)。这些模式自动注入保留状态属性,可在 BlockGUI.nonUserProvidedProperties() 中看到映射关系:

  • 模式 5(原木式)注入axis;
  • 其他非 0 模式注入facing,其中模式 1/3 若启用俯仰角(enable pitch)再注入face;
  • 若勾选 waterloggable,注入waterlogged;
  • 若设置了 block base(楼梯、活板门等),还会保留该 base 自带的属性(见blockBaseProperties)。

生成的 JSON 在 block_states.json.ftl 中按模式分支输出,例如六向 + pitch 模式会生成 12 个变体(face=floor/wall/ceiling×facing=north/east/south/west,各带对应x/y旋转),原木模式则生成axis=x/y/z三个变体。若用户又定义了自定义状态条目,模板会在每个旋转组合上继续叠加自定义属性谓词(conditionExtra与variantPredicate拼接),实现“旋转组合 × 自定义状态组合”的自动展开。

状态属性类型、组合上限与保留名

自定义属性在独立的“状态属性”页签中定义(帮助条目见 block_states.md)。属性支持的类型由 BlockStatePropertyUtils.getPossiblePropertyValues() 决定:

属性类型取值来源枚举值
LogicType(布尔)固定true、false
IntegerType(整数)用户设定的 min/maxmin .. max的每个整数
StringType(枚举)用户提供的数组数据数组中的每个字符串

预定义属性则来自数据列表 blockstateproperties.yaml,由 fromDataListEntry() 解析(支持Logic/Integer/Enum三种type,要求带registry_name字段)。属性的注册表名通过propertyRegistryName()解析:CUSTOM:前缀属性去掉前缀直接使用,其余属性查blockstateproperties数据列表的registry_name。

组合爆炸的工程约束:同一工具类定义了硬上限MAX_PROPERTY_COMBINATIONS = 2000(BlockStatePropertyUtils.java),getNumberOfPropertyCombinations()用各属性取值数的连乘计算组合总数。这与帮助文档block_states.md的建议一致:组合越多,游戏加载越慢、内存占用越高,需要大量状态时应优先考虑 NBT 数据而非状态属性。另外,旋转、waterlogging 与 block base 占用的属性名属于内部保留,不能作为自定义属性名使用。

支持前提:并非所有方块都能使用状态系统。Block.supportsBlockStates() 表明,当方块 item 模型类型为 JAVA(自定义 Java 模型)或设置了非空 block base 时,getDefinedStates()与getStateCombinations()均返回空列表,状态列表控件也会被禁用(BlockGUI.java)。

生成产物:variants 与 multipart 两种 blockstates JSON

状态列表最终生成方块所在包的blockstates/<名称>.json。从 block_states.json.ftl 模板可以看出两种格式的差异:

  • variants(默认):模板取data.getStateCombinations()(含自动补全的组合),每个组合生成一条"prop=value,..."谓词到模型的映射;renderType == -1的补全组合直接指向基础模型${registryname},自定义条目指向${registryname}_${index};
  • multipart:模板取data.getDefinedStates()(不做笛卡尔积展开),输出"multipart": [ { "when": {...}, "apply": { "model": ... } } ]列表;空条件部件省略when字段,实现“始终渲染”。

这与 multipart_model.md 文档描述的语义完全对应:multipart 下世界渲染不再使用默认方块模型(需要常显的几何体应添加空条件部件)、粒子纹理统一使用方块默认粒子纹理、碰撞体为所有匹配部件包围盒的并集(未匹配任何部件的状态碰撞体为空)。碰撞体并集逻辑在生成的 Java 代码模板 block.java.ftl 中实现:multipart 模式下makeShapes()从Shapes.empty()起累加Shapes.or(...),variants 模式则按if/else返回单个包围盒。

实战建议

结合帮助文档与源码实现,在 MCreator 中配置状态列表时建议遵循以下要点:

  1. 先想清楚属性集合:variants 格式下所有条目必须使用同一组属性,且缺失组合会自动回落到默认模型——这既是便利(无需穷举),也意味着“只有部分属性组合显示特殊模型”的场景应改用 multipart 格式;
  2. 控制组合数:组合总数受MAX_PROPERTY_COMBINATIONS = 2000限制,且组合越多加载越慢;状态很多时考虑 NBT 数据方案;
  3. 善用自动旋转:需要朝向/轴变化的方块(门、按钮、原木类)直接在旋转模式下工作,MCreator 会自动生成facing/face/axis组合,无需手工逐条罗列;
  4. multipart 注意默认模型语义:multipart 模式下世界中的默认模型不参与渲染、粒子纹理与包围盒并集规则均与 variants 不同,常显部分务必添加空条件部件。

通过以上内容,你可以在 MCreator 中完整掌握状态列表的配置方式,并理解其背后的组合补全、属性约束与模板生成机制,为开发状态驱动的自定义方块打下可靠基础。

  • 低代码
  • 代码生成
  • 桌面应用
  • 游戏开发

【免费下载链接】MCreator

MCreator is an open-source software used to make Minecraft Java Edition mods, Minecraft Bedrock Edition Add-Ons, resource packs, and data packs using an intuitive easy-to-learn interface or with an integrated code editor. It is used worldwide by Minecraft players, aspiring mod developers, for education, online classes, and STEM workshops.

项目地址:https://gitcode.com/gh_mirrors/mc/MCreator
点击查看免费下载

相关推荐

上一篇:如何快速实现Stripe风格动画导航菜单:Vue Stripe Menu完整指南
下一篇:让 Claude 调用外部工具:从工具定义到完整调用流程

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询