
在 Spigot 1.19+ 中,setCollidable(false) 已失效,无法阻止生物推挤玩家;本文提供基于 Scoreboard Team 的可靠解决方案,并附完整可部署代码。
在 spigot 1.19+ 中,`setcollidable(false)` 已失效,无法阻止生物推挤玩家;本文提供基于 scoreboard team 的可靠解决方案,并附完整可部署代码。
在开发类似“化身生物”功能的插件时(如 /mob pig 让玩家隐身并绑定一个随行生物),一个常见却棘手的问题是:尽管调用了 mob.setCollidable(false) 和 player.setCollidable(false),生物仍会持续推动玩家,导致位置偏移、卡顿甚至穿模。这是因为自 Spigot 1.19 起,setCollidable() 方法已被官方弃用(SPIGOT-6399),其底层逻辑不再生效——这不是代码疏漏,而是 API 行为变更。
Go语言(Golang)1.26.0版本提供 Go 官方 Windows amd64 MSI 安装包下载入口,版本号 1.26.0,可用于旧项目维护、兼容性测试和指定版本开发环境配置。
✅ 正确解法:使用 Scoreboard Team 控制碰撞规则
Minecraft 原生支持通过队伍(Team)配置实体/玩家间的碰撞行为。只要将玩家与召唤生物加入同一支禁用碰撞的队伍,即可 100% 阻止二者相互推挤,且不影响与其他实体的正常交互。
✅ 实现步骤(集成到你的 Mob 类中)
-
创建专用 Scoreboard 和 Team(建议在插件启用时初始化)
在 Main.java 的 onEnable() 中添加:
private Scoreboard scoreboard;
private Team mobTeam;
@Override
public void onEnable() {
this.scoreboard = Bukkit.getScoreboardManager().getNewScoreboard();
this.mobTeam = scoreboard.registerNewTeam("mob_collide_off");
this.mobTeam.setOption(Team.Option.COLLISION_RULE, Team.OptionStatus.NEVER); // 关键:禁用本队内碰撞
// 可选:隐藏队伍名称(避免显示在 Tab 列表)
this.mobTeam.setOption(Team.Option.NAME_TAG_VISIBILITY, Team.OptionStatus.NEVER);
}
-
在 onCommand() 中将玩家与生物加入该队伍
替换你原代码中 mob.teleport(...) 之前的设置部分:
// ✅ 移除已失效的 setCollidable() 调用
// mob.setCollidable(false); → 删除
// player.setCollidable(false); → 删除
// ✅ 改用 Team 方案(确保 player 和 mob 均加入同一禁碰撞队伍)
if (mobTeam != null) {
mobTeam.addEntry(player.getName());
mobTeam.addEntry(mob.getUniqueId().toString()); // 使用 UUID 避免重名冲突
}
-
清理逻辑需同步移除队伍成员
在 onPlayerQuit() 和命令重复执行(如再次输入 /mob)时,务必从队伍中移除对应条目:
// 在 mob.remove() 和 player.setInvisible(false) 后添加:
if (mobTeam != null) {
mobTeam.removeEntry(player.getName());
if (mob != null && mob.isValid()) {
mobTeam.removeEntry(mob.getUniqueId().toString());
}
}
⚠️ 注意事项
- 团队名唯一性:"mob_collide_off" 需全局唯一,避免与其他插件冲突;建议加前缀如 "snoopti_mob_team"。
- 玩家名 vs UUID:Team.addEntry() 接收字符串,玩家名可能重复(如重名玩家),强烈推荐对生物使用 mob.getUniqueId().toString(),对玩家可用 player.getName()(因退出事件中玩家已离线,但 name 仍有效)。
- 性能无负担:Scoreboard Team 是服务端原生机制,无额外 Tick 开销,远优于每 tick 手动校正位置等 hack 方式。
- 不影响其他交互:该方案仅禁用 队伍内 碰撞,玩家仍可正常攻击怪物、拾取物品、被其他生物攻击,完全符合预期行为。
✅ 最终效果验证
部署后执行 /mob zombie:
→ 玩家立即隐身,僵尸瞬移至脚下;
→ 玩家站立不动时,僵尸不会将其推开;
→ 玩家行走时,僵尸持续跟随且不产生物理干扰;
→ 其他玩家靠近时,仍会与该僵尸正常碰撞(因不在同一队伍)。
此方案已在 Paper 1.19.4 / Spigot 1.19.4 环境实测稳定运行,是当前最健壮、最符合 Minecraft 原生设计的碰撞控制方式。










