建议把声音管理器单独写一个组件,并且设置成单例模式,
另外如果不嫌麻烦的话,通过事件的方式播放可以避免很多bug
如果怕影响加载,也可以不直接拖到场景里而是存到prefab里面,然后进主页了再加载
代码大概长这样:
import { _decorator, Component, Node, AudioSource, AudioClip } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('SoundManager')
export class SoundManager extends Component {
public static instance: SoundManager = null;
onLoad() {
if (SoundManager.instance == null) {
SoundManager.instance = this;
this.init();
} else {
this.destroy();
}
}
@property(AudioSource)
music: AudioSource = null;
@property(AudioSource)
sound: AudioSource = null;
@property([AudioClip])
clipList: AudioClip[] = new Array<AudioClip>();
private clipMap: Map<string, AudioClip>;
init() {
this.clipMap = new Map();
this.clipList.forEach(item=>{
this.clipMap.set(item.name, item);
});
}
playBGM() {
// 手动播放bgm
}
playSound(id: string, volumnScale: number = 1) {
let clip = this.clipMap.get(id);
clip && this.sound.playOneShot(clip, volumnScale);
}
setEnableMusic(value: boolean) {
this.music.volume = value ? 1 : 0;
if (value) {
this.music.playing || this.music.play();
} else {
this.music.stop();
}
}
setEnableSound(value: boolean) {
this.sound.volume = value ? 1 : 0;
}
}
首页加载sound
bundle: AssetManager.Bundle;
loadResource() {
if (this.bundle) {
let time = Date.now();
this.bundle.load("prefab/Sound", Prefab, (err, prefab)=>{
if (prefab) {
const node = instantiate(prefab);
node.name = "SoundManager";
this.node.addChild(node);
console.log(`Load sound: ${(Date.now() - time) / 1000}s`);
}
})
}
}
任意组件中使用
onClickButton() {
SoundManager.instance?.playSound("btn");
}