当前位置: 移动技术网 > IT编程>开发语言>.net > 音效模块

音效模块

2019年02月02日  | 移动技术网IT编程  | 我要评论

音效系统

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);

     }
}`

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网