欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

音效模块

程序员文章站 2022-05-21 16:22:56
音效系统 1.个人思路 1.情景假设 一天,小明想听歌。于是,他拿起手机,找到音乐播放软件,选择歌曲,按下播放键,听到了想听的歌 2.过程分析 1 小明想听歌 听歌的对象,歌曲信息接收者 2 打开音乐播放软件 播放音乐的对象,音效源 3 选择歌曲 选择的数据,音效资源 3.实现思路 AudioLis ......

音效系统

1.个人思路

  • 1.情景假设

    一天,小明想听歌。于是,他拿起手机,找到音乐播放软件,选择歌曲,按下播放键,听到了想听的歌

  • 2.过程分析

    1 小明想听歌 -> 听歌的对象,歌曲信息接收者

    2 打开音乐播放软件 -> 播放音乐的对象,音效源

    3 选择歌曲 -> 选择的数据,音效资源

  • 3.实现思路

    audiolistener: 音效的监听者

    audiosources:音频控制器

    audioclip:音频文件

    音效模块

2.代码实现

2.1 简易播放器

    `using unityengine;

// 添加音效源
[requirecomponent(typeof(audiosource))]
public class audiomanagera : monobehaviour{

    public audioclip audioclip;
    private audiosource _audiosource;

    private void start()
     {
        _audiosource = getcomponent<audiosource>();
     }

    // 播放音效
    public void playaudio(float volume = 1.0f, bool isloop = false)
    {
        _audiosource.clip = audioclip;
        _audiosource.volume = volume;
        _audiosource.loop = isloop;
        _audiosource.play();
        debug.logformat("播放音效: {0}", audioclip.name);
    }
}`

`using unityengine;

public class testa : monobehaviour {

public bool isplayaudio;

void start () {
    gameobject.addcomponent<audiomanagera>();
    // 选择播放的音效
    gameobject.getcomponent<audiomanagera>().audioclip = resources.load<audioclip>("audio/backgroundmusic/bgmusic");
}

void update () {
    if (isplayaudio)
    {
        isplayaudio = false;
        gameobject.getcomponent<audiomanagera>().playaudio();
    }
}
}`

音效模块

2.2 如何方便的选择音效文件

音效模块

 `     using system;
using system.collections.generic;
using unityengine;

public interface iuploadaudio
{
    // 加载音效资源
    audioclip getaudioclip(string audioname);
}

[requirecomponent(typeof(audiosource))]
public class audiomanagerb : monobehaviour, iuploadaudio {

// 保存已经加载过的音效
private dictionary<string, audioclip> _audiodict;
private audiosource _audiosource;

private void start()
{
    _audiodict = new dictionary<string, audioclip>();
    _audiosource = getcomponent<audiosource>();
}

// 播放音效
public void playaudio(string audioname, float volume = 1.0f, bool isloop = false)
{
    if (!_audiodict.containskey(audioname))
    {
        _audiodict.add(audioname, getaudioclip(audioname));
    }
    _audiosource.clip = _audiodict[audioname];
    _audiosource.volume = volume;
    _audiosource.loop = isloop;
    _audiosource.play();
}

public audioclip getaudioclip(string audioname)
{
    audioclip audioclip = resources.load<audioclip>(audioname);
    if (audioclip == null)
    {
        throw new exception("没有找到相应的音效资源 请确认路径:" + audioname);
    }
    return audioclip;
}
}`

`using unityengine;

public class testb : monobehaviour {

public bool isplayaudio;
public string audioname;

void start()
{
    audioname = "audio/backgroundmusic/bgmusic";
    gameobject.addcomponent<audiomanagerb>();
}

void update()
{
    if (isplayaudio)
    {
        isplayaudio = false;
        gameobject.getcomponent<audiomanagerb>().playaudio(audioname);
    }
}
}`

2.2.1 使用一个音效路径管理类

`public class audiopath
{

    public const string background_music = "audio/backgroundmusic/bgmusic";
    public const string background_music_b = "audio/backgroundmusic/bgmusicb";
    public const string background_music_c = "audio/backgroundmusic/bgmusicc";
    public const string background_music_d = "audio/backgroundmusic/bgmusicd";

}`

2.2.2 使用枚举组装路径

`public class audiotype {

public enum dialogue
{

}

public enum screenonclick
{
    // 点击正确
    correct,
    // 点击错误
    error,
}

public enum specialeffects
{

}

public enum backgroundmusic
{
    // 背景音乐
    bgmusic,
}

public enum other
{

}
}`

`using unityengine;

public class testb : monobehaviour {

public bool isplayaudio;

void start()
{
    gameobject.addcomponent<audiomanagerb>();
}

void update()
{
    if (isplayaudio)
    {
        isplayaudio = false;
        gameobject.getcomponent<audiomanagerb>().playaudio(audiotype.backgroundmusic.bgmusic);
    }
}
}`

`using system;
using system.collections.generic;
using unityengine;

public interface iuploadaudio
{
// 加载音效资源
audioclip getaudioclip(enum audioname);
}

[requirecomponent(typeof(audiosource))]
public class audiomanagerb : monobehaviour, iuploadaudio
{

// 保存已经加载过的音效
private dictionary<enum, audioclip> _audiodict;
private audiosource _audiosource;
private const string audiopath = "audio/";

private void start()
{
    _audiodict = new dictionary<enum, audioclip>();
    _audiosource = getcomponent<audiosource>();
}

// 播放音效
public void playaudio(enum audioname, float volume = 1.0f, bool isloop = false)
{
    if (!_audiodict.containskey(audioname))
    {
        _audiodict.add(audioname, getaudioclip(audioname));
    }
    _audiosource.clip = _audiodict[audioname];
    _audiosource.volume = volume;
    _audiosource.loop = isloop;
    _audiosource.play();
}

public audioclip getaudioclip(enum audioname)
{
    string audiotype = audioname.gettype().name;
    audioclip audioclip = resources.load<audioclip>(audiopath + audiotype + "/" + audioname);
    if (audioclip == null)
    {
        throw new exception("没有找到相应的音效资源 请确认路径:" + audioname);
    }
    return audioclip;
}
}`

2.3 考虑多个播放源

音效模块

音效模块

2.3.1 接口设置

`public interface iuploadaudioclip
{
// 加载音效资源
audioclip getaudioclip(enum audioname);
}

public interface iuploadaudiosource
{
// 加载音效播放源
audiosource getaudiosource(string audiosourcename);
}

public interface iplayaudio
{
// 播放音效
void playaudio(enum audioname, float volume, bool isloop, string audiosourcename);
// 停止播放的音效
void stopaudio(string audiosourcename);
}`

2.3.2 播放源系统

`
public class uploadaudiosourcestrategy : iuploadaudiosource
{
// 播放的音频源
private dictionary<string, audiosource> audiosourcedict;
// 音效管理器
private gameobject audiocontrol;
private static int count;
private readonly string currentaudioname;

public uploadaudiosourcestrategy()
{
    audiosourcedict = new dictionary<string, audiosource>(3);
    audiocontrol = new gameobject { name = "audiomodulecontrol" };
    object.dontdestroyonload(audiocontrol);
    audiocontrol.addcomponent<audiolistener>();
}

public audiosource getaudiosource(string audiosourcename)
{
    if(audiosourcename.equals(string.empty))
    {
        return getcurrentaudiosource();
    }

    if (audiosourcedict.containskey(audiosourcename))
    {
        return audiosourcedict[audiosourcename];
    }

    return getcurrentaudiosource(audiosourcename);
}

private audiosource getcurrentaudiosource()
{
    foreach (var source in audiosourcedict)
    {
        if (!source.value.isplaying)
        {
            return source.value;
        }
    }
    return getcurrentaudiosource(currentaudioname + count++);
}

private audiosource getcurrentaudiosource(string audiosourcename)
{
    audiosourcedict.add(audiosourcename, audiocontrol.addcomponent<audiosource>());
    return audiosourcedict[audiosourcename];
}
}`

2.3.3 音效资源系统

`public class uploadaudioclipstrategy : iuploadaudioclip
{

// 音效路径
private readonly string audiopath;
// 播放的音效
private dictionary<enum, audioclip> audioclipdict;

public uploadaudioclipstrategy()
{
    audiopath = "audio/";
    audioclipdict = new dictionary<enum, audioclip>();
}

public audioclip getaudioclip(enum audioname)
{
    if (audioclipdict.containskey(audioname))
    {
        return audioclipdict[audioname];
    }

    audioclip clip = resources.load<audioclip>(audioclippath(audioname));
    audioclipdict.add(audioname, clip);

    return audioclipdict[audioname];
}

private string audioclippath(enum audioname)
{
    string audiotype = audioname.gettype().name;
    return audiopath + audiotype + "/" + audioname;
}
}

`

2.3.4 音效系统

`
public abstract class audiomanagerbase : iplayaudio
{
public iuploadaudiosource uploadaudiosource { get; protected set; }
public iuploadaudioclip uploadaudioclip { get; protected set; }

protected audiomanagerbase() : this(new uploadaudiosourcestrategy(), new uploadaudioclipstrategy())
{

}

protected audiomanagerbase(iuploadaudiosource uploadaudiosource, iuploadaudioclip uploadaudioclip)
{
    uploadaudiosource = uploadaudiosource;
    uploadaudioclip = uploadaudioclip;
}

public void playaudio(enum audioname, float volume, bool isloop, string audiosourcename)
{
    audioclip clip = uploadaudioclip.getaudioclip(audioname);
    audiosource audiosource = uploadaudiosource.getaudiosource(audiosourcename);
    audiosource.clip = clip;
    audiosource.volume = volume;
    audiosource.loop = isloop;
    audiosource.play();
}

public void stopaudio(string audiosourcename)
{
    audiosource audiosource = uploadaudiosource.getaudiosource(audiosourcename);
    audiosource.loop = false;
    audiosource.stop();
}
}`

`
public class audiosourcemanager : audiomanagerbase {

public const string bgaudioname = "bgaudio";

#region 播放音乐的调用方式
public void playaudio(audiotype.dialogue audioname, float volume = 1.0f, bool isloop = false, string audiosourcename = "")
{
    base.playaudio(audioname, volume, isloop, audiosourcename);
}

public void playaudio(audiotype.screenonclick audioname, float volume = 1.0f, bool isloop = false, string audiosourcename = "")
{
    base.playaudio(audioname, volume, isloop, audiosourcename);
}

public void playaudio(audiotype.specialeffects audioname, float volume = 1.0f, bool isloop = false, string audiosourcename = "")
{
    base.playaudio(audioname, volume, isloop, audiosourcename);
}

public void playaudio(audiotype.other audioname, float volume = 1.0f, bool isloop = false, string audiosourcename = "")
{
    base.playaudio(audioname, volume, isloop, audiosourcename);
}

public void playaudio(audiotype.backgroundmusic audioname, string audiosourcename = bgaudioname, float volume = 1.0f, bool isloop = true)
{
    playaudio(audioname, volume, isloop, audiosourcename);
}

#endregion

}

`


2.3.5 播放测试

`using unityengine;

public class testc : monobehaviour {

private void start()
{
    audiosourcemanager audiosourcemanager = new audiosourcemanager();
    audiosourcemanager.playaudio(audiotype.backgroundmusic.bgmusic);
    audiosourcemanager.playaudio(audiotype.screenonclick.correct);
    audiosourcemanager.playaudio(audiotype.screenonclick.error);
}
}`

2.4 常用方法扩展

`public interface iuploadaudiosource
{
   。。。
// 停止选择的部分音效
void stopgroupaudio(func<string, bool> stopgroupaudio);
}`

`public class uploadaudiosourcestrategy : iuploadaudiosource{
    。。。
    public void stopgroupaudio(func<string, bool> stopgroupaudio)
    {
         foreach (var source in audiosourcedict)
        {
             if (stopgroupaudio(source.key))
                {
                    source.value.loop = false;
                    source.value.stop();
                }
         }
    }
}`

`public abstract class audiomanagerbase : iplayaudio{
     。。。
     public void reset(func<string, bool> stopgroupaudio)
     {
       uploadaudiosource.stopgroupaudio(stopgroupaudio);
      }

     public float playaudiotime(enum audioname)
     {
         if (uploadaudioclip.getaudioclip(audioname) == null)
            {
                debug.log("error: " + "the music file could not be found");
                return 0.0f;
            }
        return uploadaudioclip.getaudioclip(audioname).length;
     }
}`

`public class audiosourcemanager : audiomanagerbase, isingleton
{
    。。。
    private audiosourcemanager() { }

    public const string bgaudioname = "bgaudio"; }`

`public class testc : monobehaviour {

    private void start()
    {
         singletonmanager.getsingleton<audiosourcemanager>().playaudio(audiotype.backgroundmusic.bgmusic);
         singletonmanager.getsingleton<audiosourcemanager>().playaudio(audiotype.screenonclick.correct);
         singletonmanager.getsingleton<audiosourcemanager>().playaudio(audiotype.screenonclick.error);

     }
}`