目录
我们可以利用 AkEvent 和 AkAmbient 组件实现回调,也可将回调添加到 Wwise 专有 Event(事件)。该流程需要同样类型的信息(Callback Function 和 Callback Flag)。不过,在通过自定义脚本实现回调时,我们可以根据特定游戏机制或对象类型来定制回调,而不用受限于某一个具体的游戏对象。自定义脚本适合处理即时状况。比如,引用的游戏对象因为被《Wwise Adventure Game》的某个环境场景卸载而变得不可用。在前面的章节中,我们使用了来自 Music_Region Event 的 MusicSyncBar 的回调,以此调用了 RhythmActions 脚本并实现了 Tree(大树)的伸缩效果。“利用 AkEvent 组件设置回调”这种方式对只有几个选定游戏对象的情形来说效果挺好。因为不必编写脚本,直接拖放就可以。不过,随着素材数量的不断增加,“通过编写自定义脚本来实现回调”会便利很多。这样的话就不必在 AkEvent 组件中创建一长串回调条目。接下来,我们要通过回调通知来调节多个环境游戏对象的比例。首先,我们会利用 Wwise 专有 Event 属性来通过脚本发送 Music_Region Event。然后,对脚本进行扩展以使其包含 Callback 函数,进而通过 RhythmActions 脚本来调用场景中的各个游戏对象。
-
在 Unity 菜单栏中,依次转到 Audiokinetic > Certification > 301 > Lesson 7,然后选择 Callbacks on a Wwise-Type Event。
我们首先要创建脚本,然后再创建 Wwise 专有 Event 属性。
-
在 Hierarchy 中,选中 Wwise 游戏对象。
-
在 Inspector 中,单击 Add Component,然后搜索 PostMusic,接着转到 New Script 并单击 Create and Add。
-
双击打开 PostMusic 脚本。
首先,我们要使用 Wwise 专有 Event 类来创建和发送 Event。
-
在 PostMusic 脚本之内、所有函数之外,键入 public Ak.Wwise.Event,以此声明一个 public 类型的 Wwise 专有 Event。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PostMusic : MonoBehaviour { public AK.Wwise.Event // 使用此函数进行初始化。 void Start () { } // 每帧调用 Update 函数一次。 void Update () { } }
-
在 AK.Wwise.Event 之后添加一个空格,然后将属性命名为 MusicEvent,最后添加一个分号 ; 来结束该代码行。
public class PostMusic : MonoBehaviour { public AK.Wwise.Event MusicEvent;
现在我们创建了 Wwise 专有 Event 属性,接下来可以在 Start 状态下发送 Event。这样的话一旦游戏初始化便会发送 Event。
-
在 Start() 函数之内,键入 MusicEvent.Post(gameObject);。
public class PostMusic : MonoBehaviour { public AK.Wwise.Event MusicEvent; // 使用此函数进行初始化。 void Start () { MusicEvent.Post(gameObject); }
对于组件,在为 Event 设置回调时,需要在发送 Event 的同时提供回调信息(Callback Flag 和 Callback Function)。另外,还要提供第二项输入参数 Callback Flag(第一项输入参数为 Game Object)。它需要通过 AkCallbackType 类来实现。对于 Post(),则可通过在 Start() 函数之内键入逗点 , 并后跟属性名称来直接添加 Callback Flag。
注意,并非全部 Callback Flag 都与所有 Wwise Object 类型兼容。比方说,假如您想在 Destruction_VolcanicBoulder_Impacts Event 结束后进行回调,可以使用 AK_EndOfEvent CallbackFlag。但是,因为该 Event 没有播放 Music Segment,所以并不会调用 AK_MusicSyncBar。
-
在 gameObject 之后,添加一个逗点 , 和一个空格,然后键入 AkCallbackType.AK_MusicSyncBar;。
void Start () { MusicEvent.Post(gameObject, AkCallbackType.AK_MusicSyncBar); }
这样便会检查 AkCallbackType 类的 AK_MusicSyncBar Flag,并将其添加到所发送的 Event。不过,对于 Post 函数,我们还要专门以 uint 属性类型的方式来发送 AK_MusicSyncBar。
利用 C# 编程语言(本项认证课程中所用编程语言),我们可以在整数 (int) 属性类型中存储不含小数位的数字。该属性类型既可存储正数也可存储负数(取值范围为 -2,147,483,648 ~ 2,147,483,647)。不过,假如要确保所有数字都是正数,您可以添加无符号前缀 u,将其设为无符号整数 uint(取值范围为 0 ~ 4,294,967,295)。
您可以通过在 CallbackType 属性之前在括号中键入新的属性类型来转换属性。
将某一属性转换为另一类型的过程称为类型转换。
-
在 AkCallbackType.AK_MusicSyncBar 之前插入 (uint)。
MusicEvent.Post(gameObject, (uint)AkCallbackType.AK_MusicSyncBar);
您有没有注意到 Post 函数下方显示了一条红色短线?
这是因为目前尚未声明在 Wwise 回叫 Unity 时调用哪个函数。接下来,我们重命名 Update() 函数。这样可以避免 Unity 自动调用它,以此将其设为 Callback 函数。
-
将 Update() 重命名为 CallbackFunction()。
// 每帧调用 Update 函数一次。 void CallbackFunction(){ }
为了避免引起误解,我们来同时删除上面有关 Update() 函数的备注。
-
删除备注“// 每帧调用 Update 函数一次。”。
void CallbackFunction(){ }
接下来,我们将函数名称添加到 Post() 函数中。
-
在 MusicEvent.Post(gameObject, (uint)CallbackType 之后,键入 , CallbackFunction 以将 CallbackFunction 作为参数添加到函数中。
MusicEvent.Post(gameObject, (uint)AkCallbackType.AK_MusicSyncBar, CallbackFunction);
我们注意到,CallbackFunction 下方的红色短线消失了。
在 Post() 函数之内添加回调函数后,Wwise 声音引擎一旦遇到所选 Callback Type 便会调用该回调函数。因为我们选择了 Callback Type AK_MusicSyncBar,所以 Wwise 声音引擎将会在进行到音乐中每一小节时调用回调函数。
不过,Wwise 声音引擎还需要回调函数能够接收有关回调通知的信息。所以,CallbackFunction 必须要能接收该信息。也就是说,不管需不需要,都得在函数的圆括号之内声明若干变量。
-
在 CallbackFunction() 的圆括号之内,键入 object in_cookie, AkCallbackType in_type, object in_info。
void CallbackFunction(object in_cookie, AkCallbackType in_type, object in_info){ }
如此一来,便可获取有关回调的信息,比如它属于哪种 Callback Type。因为我们只会接收一个回调(即 MusicSyncBar),所以目前并不需要这些参数。
如需进一步了解 Callback 函数中的这些输入属性,请参阅 Wwise SDK 文档。
现在我们成功地设置了回调,不过目前尚未指定要拿它来做什么,CallbackFunction() 仍是空的。最终,我们需要在游戏中调用各个 RhythmActions 组件。为了本次演示,我们在 GameManager 中创建了一个所有 RhythmActions 组件都要检测的函数。GameManager 脚本是个单一实例。也就是说,只能有一个这种实例,并且不会在游戏当中销毁。所以,我们可以确定该函数始终都是可用的。
在运行时将 RhythmActions 脚本实例化之后,会自动创建与 GameManager 的关联。这样就可以通过 GameManager 进行统一调用。
-
在 CallbackFunction() 函数之内,键入 GameManager.PushRhythmAction();。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PostMusic : MonoBehaviour { public AK.Wwise.Event MusicEvent; // 使用此函数进行初始化。 void Start () { MusicEvent.Post(gameObject, (uint)AkCallbackType.AK_MusicSyncBar, CallbackFunction); } void CallbackFunction(object in_cookie, AkCallbackType in_type, object in_info){ GameManager.PushRhythmAction(); } }
好样的!我们完成了本节课程中的所有脚本编写步骤,现在可以保存脚本了。接下来,我们要将 Wwise 专有 Event 属性指派给 Music_Region Event。
-
在 MusicEvent 属性中,依次展开 Events > Music > General,然后双击 Music_Region。
接下来,我们可以将 RhythmActions 脚本指派给场景中的游戏对象。假如游戏设置允许,它们就会随着音乐节奏舞动。
游戏世界环境(Desert、Forest 等)当中所用的有些游戏对象设成了静态。假如游戏对象被设为静态,在运行时将无法随着音乐节奏舞动。为此,可在 Inspector 顶部取消选中游戏对象的 Static 设置。
-
在 Hierarchy 中,选中所有以 TrainingArea_ 为开头的游戏对象。
通过选中这些游戏对象并选择 Add Component,可将组件同时添加到选中的各个对象。
-
在 Inspector 中,单击 Add Component,然后搜索并选中 RhythmActions。
现在,我们成功地通过自定义脚本将 RhythmActions 添加到了多个游戏对象,从而将回调这一核心功能巧妙地整合到了游戏中。下面来试试吧。
-
进入 Play 模式。我们注意到,刚才选中的所有对象都会按照音乐的速度舞动。
您可以自由地调节游戏对象的伸缩幅度,并将更多 RhythmActions 脚本添加到场景中的其他游戏对象。
回调系统设置好了,而且能够正常运行。在 Region_Music Event 进行到 Music Segment 中的小节时,将会调用所有与 RhythmActions 脚本绑定的游戏对象。为了实现这一点,我们在 PostMusic 脚本中设置了 Callback,并以此调用了 GameManager 中的 PushRhythmAction() 函数。相对于前面的章节,我们在此阐明了如何通过代码来设置回调,并以此来灵活地处理卸载的对象,或者快速地将回调添加到诸多对象。