【Unity】【Wwise】具体某一音频的暂停、恢复和终止播放

【Unity】【Wwise】具体某一音频的暂停、恢复和终止播放

以下内容为个人拙见,欢迎大家指正讨论。

Wwise在Unity中提供的方法中,并没有直接提供(看起来没有直接提供。。)暂停音效的方法。
在游戏中较为常见的需要停止音效(或者说控制音效播放状态)的场景,有在切换场景Loading读条时、某种游戏内置音乐播放器中等等。

音效控制场景建议

  • 对于切换场景时(或氛围变化)的音乐切换,推荐在Wwise中创建切换事件来实现,这也是使用Wwise的原因之一,在Wwise中可以圆滑的处理音频之间的切换,也可以通过总线来控制一整组的音频。
  • 对于单一音频的控制,则有以下几种方式(重点是第3条):

音效播放状态控制

  1. Wwise的Unity集成包里提供的组件AkEvent
    在这里插入图片描述

    该组件上面提供了Stop()方法

    • 优点:简单
    • 缺点:不灵活,依赖于组件;没有暂停、恢复方法。
  2. 在Wwise工程中定义对应的Stop、Pause、Resume事件,通过发送事件来控制音效

    // xxx指代某命名的音频
    AkSoundEngine.Post("Stop_xxx");
    AkSoundEngine.Post("Pause_xxx");
    AkSoundEngine.Post("Resume_xxx");
    
    • 优点:较为灵活,可以在任意地方调用
    • 缺点:需要定义3倍于播放事件的操控事件,在Wwise中的工作量巨大;对同一音效的控制分离,难于管理
  3. 封装Wwise提供的方法来实现Stop、Pause、Resume三种控制
    既然在AkEvent中有Stop方法,那么可以深入查看一下内部是怎么实现的,最后就找到了以下方法

    public static AKRESULT ExecuteActionOnEvent(uint in_eventID, 
    	AkActionOnEventType in_ActionType, 
    	UnityEngine.GameObject in_gameObjectID, 
    	int in_uTransitionDuration,
    	AkCurveInterpolation in_eFadeCurve)
    

    其中的参数AkActionOnEventType有以下几种类型
    在这里插入图片描述

    所以由此可以进行以下封装(其中WwiseLogger是自己封装的,方便release中剔除):

    /// <param name="soundId">In <see cref="AK.EVENTS"/>.</param>
    public void Pause(uint soundId, GameObject soundSource = null)
    {
    	// NOTE 经过试验,Wwise的暂停和恢复走的是计数机制,暂停多少次,就需要恢复多少次才能够正常恢复。
    	if (soundId == InvalidSoundId)
    	{
    		WwiseLogger.LogMessage(WwiseLogger.LogLevel.Warning, string.Format("Invalid soundId.", soundId));
    		return;
    	}
    
    	var result = AkSoundEngine.ExecuteActionOnEvent(soundId, AkActionOnEventType.AkActionOnEventType_Pause, soundSource);
    	if (result != AKRESULT.AK_Success)
    		WwiseLogger.LogMessage(WwiseLogger.LogLevel.Warning, string.Format("Pause wwise event with id <{0}> failed.", soundId), result);
    	else
    		WwiseLogger.LogMessage(WwiseLogger.LogLevel.Normal, string.Format("Pause event with id <{0}>.", soundId));
    }
    
    /// <summary>
    /// Should call the same times with Pause.
    /// </summary>
    /// <param name="soundId">In <see cref="AK.EVENTS"/>.</param>
    public void Resume(uint soundId, GameObject soundSource = null)
    {
    	// NOTE 经过试验,Wwise的暂停和恢复走的是计数机制,暂停多少次,就需要恢复多少次才能够正常恢复。
    	if (soundId == InvalidSoundId)
    	{
    		WwiseLogger.LogMessage(WwiseLogger.LogLevel.Warning, string.Format("Invalid soundId.", soundId));
    		return;
    	}
    
    	var result = AkSoundEngine.ExecuteActionOnEvent(soundId, AkActionOnEventType.AkActionOnEventType_Resume, soundSource);
    	if (result != AKRESULT.AK_Success)
    		WwiseLogger.LogMessage(WwiseLogger.LogLevel.Warning, string.Format("Resume wwise event with id <{0}> failed.", soundId), result);
    	else
    		WwiseLogger.LogMessage(WwiseLogger.LogLevel.Normal, string.Format("Resume event with id <{0}>.", soundId));
    }
    
    
    /// <summary>
    /// Stop Audio.
    /// </summary>
    /// <param name="soundId">Wwise event id, defined in <see cref="AK.EVENTS"/></param>
    /// <param name="soundSource">发声源</param>
    /// <param name="transitionDuration">停止所需时间,单位为毫秒(ms)</param>
    /// <param name="curveInterpolation">音量变化曲线</param>
    public void Stop(uint soundId, GameObject soundSource = null, int transitionDuration = 0, AkCurveInterpolation curveInterpolation = AkCurveInterpolation.AkCurveInterpolation_Linear)
    {
    	var result = AkSoundEngine.ExecuteActionOnEvent(soundId, AkActionOnEventType.AkActionOnEventType_Stop,
    		soundSource == null ? gameObject : soundSource, transitionDuration, curveInterpolation);
    	if (result != AKRESULT.AK_Success)
    	{
    		WwiseLogger.LogMessage(WwiseLogger.LogLevel.Warning, string.Format("Stop event with id <{0}> failed.", soundId), result);
    		return;
    	}
    }
    

    需要注意的是,经过试验,wwise的暂停和恢复走的是计数机制,暂停多少次,就需要恢复多少次才能够正常恢复。

    • 优点:非常灵活,无需定义大量时间
    • 缺点:基于计数的暂停和恢复在复杂的游戏业务里可能会难以正确控制
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值