请问3.x如何通过string音频名称播放audioclip

跨脚本调用
this.AudioScript.playOneShot('Doo',1)

image
对象挂载 方式引入clip
image
结果显示播放无效
image

官方给的这个参考. 音频播放示例,直接copy有问题…

    playSound (name: string, volumeScale: number = 1 ) {
        const audioSource = audioManager._audioSource!;
        assert(audioSource, 'AudioManager not inited!');

        // 注意:第二个参数 “volumeScale” 是指播放音量的倍数,最终播放的音量为 “audioSource.volume * volumeScale”
        audioSource.playOneShot(audioClip, volumeScale);

    }

error:无法识别audioClip

假如我在同脚本可以直接用
this.playOneShot(this.Doo,1)

跨脚本我可以用
this.AudioScript.playOneShot(this.AudioScript.Doo,1)

但是现在的情况是我要在预制体里播放不同名称音频,我想了个办法
image
但是这样好像有很麻烦,难道现在只能用assetManager加载了嘛

建议把声音管理器单独写一个组件,并且设置成单例模式,
另外如果不嫌麻烦的话,通过事件的方式播放可以避免很多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");
}
1赞

好详细,太棒了谢谢