You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Minecraft Forge 1.20.1战斗音乐模组音效无法播放问题求助

Minecraft Forge 1.20.1战斗音乐模组音效无法播放排查求助

正在开发一款类似《原神》的Minecraft Forge 1.20.1战斗音乐模组,核心需求:玩家被敌对生物攻击时播放战斗音乐,当玩家15格范围内无敌对生物时停止音乐。当前攻击检测与逻辑触发均正常(日志能输出"Attempting to play custom sound"及正确的敌对生物数量),但实际无声音播放。

代码模块说明

1. onAttack方法

负责检测被攻击实体是否为LocalPlayer,验证世界难度非和平模式,调用getEntities获取附近敌对生物数量,数量大于0时触发playCustomSound:

@SubscribeEvent
public void onAttack(final LivingAttackEvent event) {
    LivingEntity entity = event.getEntity();
    if (entity instanceof LocalPlayer player) {
        Minecraft mc = Minecraft.getInstance();
        SoundManager manager = mc.getSoundManager();
        if (mc.level != null && mc.level.getDifficulty() != Difficulty.PEACEFUL) {
            int hostileMobs = getEntities(player);

            LOGGER.info("Hostile Mobs Nearby: " + hostileMobs);

            if (hostileMobs > 0) {
                if (!manager.isActive(lastSound)) {
                    LOGGER.info("Attempting to play custom sound");
                    playCustomSound(); // Call the custom method to play the sound
                    decaySeconds = 0;
                }
            } else {
                LOGGER.info("No hostile mobs nearby");
                // If there are no hostile mobs within 15 blocks, stop the sound
                if (manager.isActive(lastSound)) {
                    LOGGER.info("Stopping the custom sound");
                    manager.stop(lastSound);
                    lastSound = null;
                }
            }
        }
    }
}

2. getEntities方法

正常工作,可返回正确的敌对生物数量:

private int getEntities(LocalPlayer player) {
    return player.clientLevel.getEntitiesOfClass(Monster.class, new AABB(-12D, -10D, -12D, 12D, 10D, 12D).move(player.getX(), player.getY(), player.getZ()), mob -> mob.canAttack(player)).size();
}

3. playCustomSound方法

疑似问题所在。已确认ModSounds中注册的UNIV_BRAWL SoundEvent可通过/playsound命令正常播放,但调用此方法无声音输出:

private void playCustomSound() {
    Minecraft mc = Minecraft.getInstance();
    SoundManager manager = mc.getSoundManager();

    // Replace with your registered SoundEvent
    SoundEvent soundEvent = ModSounds.UNIV_BRAWL.get();

    if (soundEvent == null) {
        LOGGER.error("SoundEvent is null. Make sure it's properly registered.");
        return;
    }

    ResourceLocation soundLocation = soundEvent.getLocation();
    LOGGER.info("Attempting to play sound: " + soundLocation.toString());

    SimpleSoundInstance soundInstance = SimpleSoundInstance.forMusic(soundEvent);
    manager.play(soundInstance);
}

ModSounds类片段

public static final DeferredRegister<SoundEvent> SOUNDS = DeferredRegister.create(ForgeRegistries.SOUND_EVENTS, "battlemusic");

public static final RegistryObject<SoundEvent> UNIV_BRAWL = SOUNDS.register(
        "combatmusic", () -> SoundEvent.createVariableRangeEvent(new ResourceLocation(battlemusic.MOD_ID, "univ_brawl")));

public static void register(IEventBus eventBus) {
    SOUNDS.register(eventBus);
}

主类battlemusic

@Mod("battlemusic")
public class battlemusic {
    public static final String MOD_ID = "battlemusic";
    public static final Logger LOGGER = LogUtils.getLogger();

    public int decaySeconds = 0;
    public SimpleSoundInstance lastSound;

    public battlemusic() {
        IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();

        ModCreativeModTabs.register(modEventBus);
        ModItems.register(modEventBus);
        ModSounds.register(modEventBus);

        modEventBus.addListener(this::commonSetup);
        modEventBus.addListener(this::addCreative);

        MinecraftForge.EVENT_BUS.register(this);
    }

    private void commonSetup(final FMLCommonSetupEvent event) {
        // Add your common setup code here
    }

    private void addCreative(BuildCreativeModeTabContentsEvent event) {
        if (event.getTabKey() == CreativeModeTabs.INGREDIENTS) {
            // Add your creative tab contents here
        }
    }
}

排查与修复建议

  • 保存SoundInstance引用:当前playCustomSound创建的SimpleSoundInstance未赋值给lastSound,导致后续manager.isActive(lastSound)判断始终为false(lastSound一直为null),且无法正确停止音乐。修改playCustomSound:
    private void playCustomSound() {
        Minecraft mc = Minecraft.getInstance();
        SoundManager manager = mc.getSoundManager();
    
        SoundEvent soundEvent = ModSounds.UNIV_BRAWL.get();
    
        if (soundEvent == null) {
            LOGGER.error("SoundEvent is null. Make sure it's properly registered.");
            return;
        }
    
        ResourceLocation soundLocation = soundEvent.getLocation();
        LOGGER.info("Attempting to play sound: " + soundLocation.toString());
    
        lastSound = SimpleSoundInstance.forMusic(soundEvent); // 赋值给类成员lastSound
        manager.play(lastSound);
    }
    
  • 确保在客户端主线程执行播放:部分事件可能在非主线程触发,用mc.execute包裹播放逻辑,确保在客户端主线程执行:
    mc.execute(() -> {
        lastSound = SimpleSoundInstance.forMusic(soundEvent);
        manager.play(lastSound);
    });
    
  • 验证SoundInstance参数配置:forMusic默认创建的实例可能不符合需求,可手动指定参数(如循环、衰减类型等):
    lastSound = new SimpleSoundInstance(
        soundEvent,
        SoundSource.MUSIC,
        1.0F, // 音量
        1.0F, // 音调
        true, // 是否循环
        0, // 延迟
        SoundInstance.AttenuationType.NONE, // 衰减类型
        mc.player.getX(),
        mc.player.getY(),
        mc.player.getZ(),
        true // 相对玩家位置
    );
    
  • 确认SoundEvent注册一致性:在playCustomSound中添加日志打印SoundEvent的注册表名称,确认与注册信息一致:
    LOGGER.info("SoundEvent registry name: " + soundEvent.getRegistryName());
    
  • 调试SoundManager状态:播放后立即打印manager.isActive(lastSound),确认SoundManager是否真正接收到播放请求。

内容的提问来源于stack exchange,提问作者Meya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 04:53:19