Minecraft mod开发:给玩家添加的药水效果无法触发生效问题求助
问题排查及修复方案
- 事件未注册:Forge事件体系要求监听类/方法必须注册到事件总线才会被触发。请确认当前方法所在类已经添加
@EventBusSubscriber注解,或者手动将类实例注册到Forge.EVENT_BUS中。 - 事件侧别错误:你选用的
InputUpdateEvent仅在客户端线程触发,药水添加、物品修改、消息发送这类需要同步的逻辑直接在客户端执行会被服务端数据回滚,看起来就像没有触发效果。 - 方块位置判断偏差:
player.getPosition().down()获取的坐标可能和你预期的脚下方块不符。可以在代码中增加日志打印block.getBlock().getRegistryName()的输出,确认是否匹配你注册的铜块ID。 - 物品匹配逻辑遗漏:如果你的铜线物品存在自定义NBT标签,或者你注册的物品实例和判断的实例不统一,也会导致判断不通过。可以同步打印
mainHand.getItem().getRegistryName()排查匹配问题。
推荐修复代码
// 类上添加EventBusSubscriber注解自动注册到事件总线 @EventBusSubscriber public class CopperEffectHandler { @SubscribeEvent public static void onPlayerTick(TickEvent.PlayerTickEvent event) { PlayerEntity player = event.player; // 仅在服务端执行逻辑,避免同步问题 if (player.world.isRemote) return; // 仅在tick的START阶段执行一次,避免重复触发 if (event.phase != TickEvent.Phase.START) return; // 潜行判断 if (!player.isCrouching()) return; ItemStack mainHand = player.getHeldItemMainhand(); // 提前判断主手物品,减少不必要的逻辑执行 if (mainHand.isEmpty() || mainHand.getItem() != ModItems.COPPER_WIRE.get()) return; // 获取脚下方块 BlockPos standingBlockPos = player.getPosition().down(); BlockState standingBlock = player.world.getBlockState(standingBlockPos); if (standingBlock.getBlock() != ModBlocks.COPPER_BLOCK.get()) return; // 所有条件满足,执行效果逻辑 player.addPotionEffect(new EffectInstance(Effects.STRENGTH, 100, 0)); player.addPotionEffect(new EffectInstance(Effects.REGENERATION, 100, 0)); player.addPotionEffect(new EffectInstance(Effects.FIRE_RESISTANCE, 100, 0)); mainHand.shrink(1); String msg = TextFormatting.RED + "YOU JUST ENTER IN GOD MODE!!!"; player.sendMessage(new StringTextComponent(msg), player.getUniqueID()); } }
额外注意事项
- 原逻辑没有做冷却判断,会导致玩家持有的铜线每秒被消耗20次(游戏tick频率),瞬间被用完。如果要限制触发频率,可以给玩家加上NBT标签记录上次触发时间,间隔大于你设定的冷却时间再允许触发。
- 药水效果的时长100tick等于5秒,如果你希望效果持续存在可以加长时长,或者每次触发时判断如果已经有该效果就刷新时长。
内容的提问来源于stack exchange,提问作者Ganoss_
相关产品推荐
相关产品推荐

