- 低代码
- 代码生成
- 桌面应用
- 游戏开发
【免费下载链接】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.
MCreator 的普通物品(Item)与工具(Tool)元素都内置了两个极易混淆的「右键」事件:当右键点击空气时(右击空气时)与当右键点击方块时(右击方块时)。本文以插件仓库中对应帮助文档 item/when_right_clicked.md 为骨架,结合 item/when_right_clicked_block.md 与生成器源码,讲清两个事件的触发时机、依赖项、ActionResultType(SUCCESS/CONSUME/PASS/FAIL)的语义,以及如何用返回值控制「空中右键」与「方块右键」两个事件的分流。读完你将能精确设计出「右键物品打开 GUI」「右键空气才触发的技能」「右键方块才生效的交互道具」等典型玩法,并知道生成后的 Java 代码长什么样。
两个右键事件:触发时机与坐标差异
在物品(Item)或工具(Tool)元素的事件列表中,MCreator 提供了两个看似相同、实则分工明确的事件。对应本地化文案(见 texts_zh_CN.properties 中的elementgui.common.event_right_clicked_air/event_right_clicked_block)清楚地体现了差异:
| 事件 | 界面文案(中文) | 触发条件 | 记录坐标 |
|---|---|---|---|
onRightClickedInAir | 右击空气时(实体的位置) | 玩家手持该物品右键,且没有对准任何方块 | 实体位置(entity.getX/Y/Z) |
onRightClickedOnBlock | 右击方块时(方块的位置) | 玩家手持该物品右键,且指针指向某个方块 | 方块位置(context.getClickedPos()) |
两个事件在界面上的完整名称分别是「当右键点击时(实体的位置)」与「当右键点击方块时(方块的位置)」,英文原文为When right-clicked (entity pos.)与When right-clicked on block (block pos.)。这里的“位置”差异是使用中最容易踩坑的地方:如果你的流程依赖坐标参数,务必确认自己用的是实体坐标还是方块坐标。
依赖项(Dependencies)一览
在 ItemGUI.java 中可以看到两个事件注册时声明的依赖项:
onRightClickedInAir(右击空气时):x:number / y:number / z:number—— 实体坐标world:world—— 世界对象entity:entity—— 执行右键的玩家itemstack:itemstack—— 手中的物品
onRightClickedOnBlock(右击方块时):x:number / y:number / z:number——方块坐标world:world、entity:entity、itemstack:itemstack- 额外多出
direction:direction(被点击方块的朝向/面)与blockstate:blockstate(被点击方块的方块状态)
也就是说,「右击方块时」事件还向流程额外提供了“点到了哪个面、点中的方块处于什么状态”这两个上下文,适合做与方块交互的逻辑(例如对草方块施肥、对箱子开锁、根据朝向放置物品等);而「右击空气时」事件更适合做施法、举盾、开关装备等不依赖方块目标的逻辑。
两个事件各自的生成入口
「右击空气时」逻辑在生成时挂载到物品类的use()方法上。以 NeoForge 1.21.1 生成器模板 templates/item/item.java.ftl 为例:
@Override public InteractionResultHolder<ItemStack> use(Level world, Player entity, InteractionHand hand) { InteractionResultHolder<ItemStack> ar = super.use(world, entity, hand); // ... 远程武器 / 蓄力 / 右键打开 GUI 等前置逻辑 ... if (hasProcedure(data.onRightClickedInAir)) { onRightClickedInAirProcedure.execute(entity.getX(), entity.getY(), entity.getZ(), world, entity, ar.getObject()); } return ar; }「右击方块时」逻辑则挂在useOn()方法上,由公共宏onItemUsedOnBlock生成(见 utils/triggers.java.ftl,26.3 分支同构见 utils/triggers.java.ftl):
@Override public InteractionResult useOn(UseOnContext context) { super.useOn(context); // 流程执行后返回 ActionResult(若流程未返回值则回退为 SUCCESS) return onRightClickedOnBlockProcedure.execute(...) 或 InteractionResult.SUCCESS; }在工具(Tool)元素中,两个事件通过 templates/tool.java.ftl 以相同方式接入use()与useOn()。
返回值 ActionResultType:SUCCESS / CONSUME / PASS / FAIL 的语义
「右击方块时」事件是 MCreator 中少数需要(或可以)返回ActionResultType的事件之一。在 ItemGUI.java 中可以看到该事件注册时指定了返回类型ACTIONRESULTTYPE,并且.makeReturnValueOptional()——即返回值可选。可在流程编辑器的「动作结果类型」下拉块中选择,其可选值定义在 action_result_type.json:
- SUCCESS:交互成功。表示该物品确实与方块发生了交互。
- CONSUME:交互成功且消耗这次点击(不继续传递)。与 SUCCESS 类似,但语义上强调“本次点击已被消费”。
- PASS:没有发生交互,将点击事件继续传递给后续逻辑(如放置方块等默认行为)。
- FAIL:交互失败,本次点击被阻止。
对应的原版枚举为net.minecraft.world.InteractionResult,四个值直接映射到其 SUCCESS / CONSUME / PASS / FAIL。
不返回任何值时默认是 PASS
「右击方块时」帮助文档(when_right_clicked_block.md)明确说明:如果流程没有返回任何值,结果将被视为 PASS。这一点在生成宏procedureCodeWithOptResult(见 utils/procedures.java.ftl)中体现得十分直接:
<#if hasReturnValueOf(object, type)> return <@procedureCode object dependencies/> <#-- 流程返回了 ActionResultType --> <#else> <@procedureCode object dependencies/> return ${defaultResult}; <#-- 未返回,回退到默认值 --> </#if>而onItemUsedOnBlock宏传入的defaultResult是InteractionResult.SUCCESS——注意这里生成器的“代码回退值”是 SUCCESS,与文档描述存在一处细微差别:文档语义层面约定“流程未返回值视为 PASS(事件继续向后传递)”;代码回退层面则直接返回 SUCCESS。实际工程中的理解应以生成代码为准:未返回值的流程会得到InteractionResult.SUCCESS。若你需要严格的“继续传递”行为,请在流程末尾显式返回PASS。
用返回值分流:让「右击空气时」只在空中触发
这是原文档(when_right_clicked.md)重点强调的核心技巧:
如果希望「右击空气时」流程只在玩家于空中(未对准方块)右键时被调用,那么「右击方块时」流程必须始终返回 SUCCESS/CONSUME。
原理如下:当玩家右键时,Minecraft 会先尝试对指针指向的方块调用useOn()(即「右击方块时」)。如果该方法返回 PASS,点击事件会被“放行”并继续触发use()(即「右击空气时」);如果返回 SUCCESS/CONSUME,则点击被判定为已处理,use()不再被调用,因此「右击空气时」不会触发。
由此得出两条实用规则:
- 想要空中右键生效、方块右键也生效:保持默认。右击方块时事件返回 PASS(或不返回值),
use()与useOn()都会执行。 - 只想要空中右键生效(方块右键不触发空中逻辑):在「右击方块时」流程末尾放置一个「动作结果类型」块并设置为SUCCESS 或 CONSUME。这样对准方块右键时事件被消费,空中逻辑不会运行;而对空右键时
useOn()根本不会被调用,空中逻辑照常执行。
反之,如果「右击方块时」返回 PASS,那么玩家右键任何方块时,空中右键流程也会一并执行——这常常导致“想点方块触发 A,结果空中技能 B 也被触发了”的 bug。
实战场景:三种典型设计
结合 Item.java 中声明的三个字段(openGUIOnRightClick、onRightClickedInAir、onRightClickedOnBlock),以下是常见玩法与事件配置对照:
| 需求 | onRightClickedInAir | onRightClickedOnBlock | 说明 |
|---|---|---|---|
| 右键物品打开 GUI | 可留空 | 留空 | 使用元素自带「右键时打开 GUI」开关(openGUIOnRightClick),无需流程。注意:若同时绑定 GUI 与两个右键流程,生成逻辑会先处理 GUI 打开,再执行流程(见 item.java.ftl) |
| 右键方块施肥/放火,空中不触发 | 留空 | 执行逻辑,返回 SUCCESS | 借助blockstate判断目标方块,direction决定效果朝向 |
| 空中右键施法/蓄力,方块右键不误触 | 施法流程 | 直接返回 SUCCESS/CONSUME | 满足帮助文档的分流条件 |
生成后的完整 Java 形态(NeoForge 1.21.1)
将上述配置导出为模组后,物品类中会同时出现两个重写方法。1.21.1(NeoForge)生成的代码形如:
// 空中右键(依赖:世界、实体坐标、玩家、物品堆) @Override public InteractionResultHolder<ItemStack> use(Level world, Player entity, InteractionHand hand) { InteractionResultHolder<ItemStack> ar = super.use(world, entity, hand); if (hasProcedure(data.onRightClickedInAir)) { MyItemOnRightClickedInAirProcedure.execute(entity.getX(), entity.getY(), entity.getZ(), world, entity, ar.getObject()); } return ar; } // 方块右键(依赖:额外包含 blockstate 与 direction) @Override public InteractionResult useOn(UseOnContext context) { super.useOn(context); MyItemOnRightClickedOnBlockProcedure.execute( context.getLevel(), context.getClickedPos().getX(), context.getClickedPos().getY(), context.getClickedPos().getZ(), context.getLevel().getBlockState(context.getClickedPos()), context.getPlayer(), context.getClickedFace(), context.getItemInHand()); return InteractionResult.SUCCESS; // 若流程返回了 ActionResultType,则此处 return 流程结果 }若使用 NeoForge 26.3(较新版本线)生成器,use()的签名改为public InteractionResult use(...)(见 templates/item/item.java.ftl),但useOn()的接入方式与返回语义保持一致。因此,基于不同生成器版本排查右键问题时,优先确认InteractionResultHolder<ItemStack>与InteractionResult两种签名差异,其余逻辑结构基本相同。
常见排查清单
- 坐标用错了:空中事件用
entity.getX/Y/Z,方块事件用context.getClickedPos();不要在方块事件里误取实体坐标做放置偏移。 - 两个事件同时触发:确认「右击方块时」是否返回了 PASS(或未返回值),导致点击被放行后又执行了空中逻辑。
- 返回块类型不匹配:ActionResultType 下拉块只能在指定返回类型的事件中使用;若流程结构里没有「动作结果类型」块,生成代码会走默认回退值。
- 与 GUI 冲突:右键打开 GUI 与右键流程共用
use()入口,若 GUI 打开条件未满足,流程仍会继续执行,注意用条件块(如openGUIOnRightClick的判断)隔离。
至此,两个右键事件的触发边界、返回值语义、分流技巧与生成代码形态均已覆盖。实际开发时建议先在流程末尾显式返回PASS或SUCCESS,再结合游戏内行为观察,即可快速确定事件流向是否符合预期。
- 低代码
- 代码生成
- 桌面应用
- 游戏开发
【免费下载链接】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.
相关推荐
MCreator 方块右击事件(When Right Clicked)完整指南:ActionResult 返回语义与底层实现解析
MCreator 方块右击事件(When Right Clicked)完整指南:ActionResult 返回语义与底层实现解析 导读 本文围绕 MCreato
低代码代码生成桌面应用游戏开发PokemonRedExperiments事件触发条件:get_all_events_reward返回值解析
PokemonRedExperiments事件触发条件:get_all_events_reward返回值解析 在强化学习(Reinforcement Learn
强化学习深度学习AI应用MCreator 基岩版(Bedrock)物品教程:用"实体放置"组件制作右键生成实体的物品
MCreator 基岩版(Bedrock)物品教程:用"实体放置"组件制作右键生成实体的物品 本教程围绕 MCreator 基岩版物品(BEItem)编辑器中的
低代码代码生成桌面应用游戏开发
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考