cocos creator&微信小游戏音频播放数量限制问题

问题产生:

1、cocos creator的AudioSource,如果使用.Play()方法,微信端每次都会生成一个innerAudioContext实例。Cocos对这个实例是有规定最大播放数量限制,可以使用AudioSource.maxAudioChannel获取。

2、打包微信端最大播放限制10例,html5是24例,原生app是32。这些都是cocos自己规定的,使用cocos的音频接口就无法绕过。一旦超出就会自动停止之前的播放,造成意外停止,对音乐影响甚大。

解决:

1、可以用一个AudioSource来使用.PlayOneShot()方法播短音效,不会列入计数,代价是播出后的音频不受控。极简单的项目无所谓。

2、对于声音设计师,如果不能容忍播出后无法控制的情况,毕竟很多音频逻辑的构建都是基于播出后可控。可以从不超量的播放来解决,并且大多数游戏都是需要人为限制播放量,避免声音嘈杂。

2.1 音频配表增加限制、权重参数

这是我设计的一份音频配表,是否限制重复播放栏:0不限制,1不播新的,2停旧播新(默认1),基本不会配0。权重栏:1-100(默认50)。

2.2 限制重复播放

// 计数,以及是否限制重复
        if (this.playCountMap.has(audioName)) {
            if (limit == 1 && this.playCountMap.get(audioName)! > 0) {
                this.Log(`限制重复 ${audioName} 不播出!`);
                return;
            } else if (limit == 2 && this.playCountMap.get(audioName)! > 0) {
                this.Log(`限制重复 ${audioName} 停旧播新!`);
                for (let handler of this.playingPool) {
                    // 实际上是旧的进度拉到0,不新增播放器
                    if (handler.name === audioName) {
                        if (handler.isStopping) {
                            handler.isStopping = false;
                        }
                        handler.fadeTween?.stop();
                        let as = handler.audioNode.getComponent(AudioSource)!;
                        if(handler.delayCall){
                            as.unschedule(handler.delayCall);
                            handler.delayCall = null;
                        }
                        // 进度回到起始
                        as.currentTime = 0;
                        // 重新计时停止和回收
                        handler.delayCall = () => {
                            this.stopSound(handler);
                        }
                        as.scheduleOnce(handler.delayCall, as.duration);
                        as.volume = PlaySettingM.getSoundVolume();
                        break;
                    }
                }
                return;
            }
        } else {
            this.playCountMap.set(audioName, 0);
        }

在音频管理器的播放方法内,判断是否发生重复,再根据配表执行相应操作。一般的技能音效适合不播新的,按钮类、十连抽爆奖类适合停旧播新。我的停旧播新逻辑,实际上是不新增播放,只是把旧的播放进度拉回0。

有限制重复加持,就比较不容易超出播放量。也不容易发生大量叠加播放,造成听觉上的灾难。

**可以用一个AudioSource来使用.PlayOneShot()方法播短音效(配置“不限制重复”或者“不播新”时),其他的AudioSource仍然使用play方法来播放音乐、循环音效、配置“停旧播新”的短音效。

2.3 发生超量时,权重系统起作用

   /**
     * 检查播放数量
     * @param weight 新一例播放的权重
     */
    private checkPlayCount(weight: number) {
        if (this.playingPool.length >= this.maxPlayCount) {
            this.playingPool.sort((a, b) => a.weight - b.weight);
            if (weight > this.playingPool[0].weight) {
                let as = this.playingPool[0].audioNode.getComponent(AudioSource)!;
                if (as.loop && this.playingPool[0] != this.curBGMPlayer) {
                    this.stopLoopSound(this.playingPool[0].name);
                } else {
                    this.stopSound(this.playingPool[0]);
                }
            } else {
                return false;
            }
        }
        return true;
    }

超量时,播出列表按权重升序。来判断究竟是停掉最低权重的播放器,还是不播最低权重的新实例。

**播完时,需要对播放器的audioSource执行.stop(),才会销毁该innerAudioContext实例。播循环音频时,一定会手动停止,那时去停止即可。单遍短音效需要tween来计时停止。

3、确实想在微信端突破最大播放数量限制,构造更复杂的播放功能时。可以改为直接调用微信的InnerAudio或者webAudio。即抛弃cocos的音频接口。

这样超量有可能会增加小程序的性能负担,另外其他平台如原生app、html5还是需要使用cocos音频接口或者它们的原生接口。

  • 13
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值