第 7 课

目录

Callbacks on a Wwise-Type Event

While you can enable callbacks on the AkEvent and AkAmbient components, you can also add callbacks to a Wwise-Type Event. The process requires the same types of information (Callback Function and the Callback Flag); but, by enabling callbacks from a custom script, you can tailor your callbacks towards a specific game mechanic or object type rather than a particular instance of a game object. Using a custom script allows for contingencies where, for example, a referenced game object is not available because it is unloaded by one of the Wwise Adventure Game's Environment Scenes. In the previous section, you used the callback from the Music_Region Event's MusicSyncBar to call the RhythmActions script that would scale a Tree up and down. Setting a callback with the AkEvent component is good for a few selected game objects as you can easily drag it in without having to write a script.However, once you start to have a substantial amount of assets, you would greatly benefit from writing a custom script for your callback needs, saving you from having to create a lengthy list of callback entries in an AkEvent component. In the following steps, you will be asked to change multiple environment game objects' scale on a callback notification. First, you will post the Music_Region Event from script using a Wwise-Type Event property. Then you will extend the script to include a Callback function, from which you'll call various game objects in the Scene using the RhythmActions script.

  1. In the Unity menu, go to Audiokinetic > Certification > 301 > Lesson 7 and select Callbacks on a Wwise-Type Event.

    First, you'll create the script and create the Wwise-Type Event property.

  2. In the Hierarchy, select the Wwise game object.

  3. In the Inspector, click Add Component, search for PostWwiseEvent, go to New Script, and click Create and Add.

  4. Double-click the PostWwiseEvent script to open it.

    First, you will need to create and post the Event using the Wwise-Type Event class.

  5. Inside the PostWwiseEvent script and outside any function, declare a public Wwise-Type Event by writing public Ak.Wwise.Event.

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
        
    public class PostWwiseEvent : MonoBehaviour {
        public AK.Wwise.Event
        // Use this for initialization
        void Start () {
        
        }
        // Update is called once per frame.
        void Update () {
        
        }
    }

  6. After AK.Wwise.Event add one space, name the property MusicEvent, and end the line with a semicolon ( ;).

    public class PostWwiseEvent : MonoBehaviour {
        public AK.Wwise.Event MusicEvent;
    

    Now that you've created a Wwise-Type Event property, you can post the Event in Start, so the Event will be posted first thing once the game is initialized.

  7. In the Start() function, type " MusicEvent.Post(gameObject);".

    public class PostWwiseEvent : MonoBehaviour {
        public AK.Wwise.Event MusicEvent;
        // Use this for initialization.
        void Start () {
            MusicEvent.Post(gameObject);        
        }
    

    As with components, when setting up callbacks for an Event, you need to give the callback information (Callback Flag and Callback Function) along with posting the Event. The Callback Flag is the second input parameter (the first input parameter is game object), which is achieved through the AkCallbackType class. For Post(), you can simply add the Callback Flag as well by writing a comma (,) followed by the name of the property in the Start() function.

    [Note]

    Note that not all Callback Flags are compatible with all Wwise Object types. For example, should you want a callback on when the Destruction_VolcanicBoulder_Impacts Event has ended, you can use the AK_EndOfEvent CallbackFlag, but the AK_MusicSyncBar would not be called as the Event is not playing a Music Segment.

  8. Continuing from gameObject, add one comma (,), one space, and type AkCallbackType.AK_MusicSyncBar;

    void Start () {
        MusicEvent.Post(gameObject, AkCallbackType.AK_MusicSyncBar);
    }

    This will look inside the AkCallbackType class for the AK_MusicSyncBar Flag and add it to the posted Event. Specifically for the Post function, you also need to send the AK_MusicSyncBar as a uint property type.

    [Note]

    In the C# programming language (the programming language used in this certification), you can store a number without decimals in the property type called integer (int). The property type can store both positive and negative numbers (value ranging from -2,147,483,648 to 2,147,483,647), but to make sure all numbers are positive, you can add the unsigned prefix 'u', hereby making it an unsigned int, written as uint (value ranging from 0 to 4,294,967,295).

    You can convert a property by adding the new property type in parentheses before the CallbackType property.

    [Tip]

    Converting one property to another type is called Typecasting.

  9. Insert (uint) in front of AkCallbackType.AK_MusicSyncBar.

    MusicEvent.Post(gameObject, (uint)AkCallbackType.AK_MusicSyncBar);

    Notice that there is a small red line under the Post function?

    This is because you have not declared what function should be called once Wwise calls back to Unity. Let's rename the Update() function, so it will not be called by Unity, and make it into a Callback function.

  10. Rename Update() into CallbackFunction()

        // Update is called once per frame.
        void CallbackFunction(){
        
        }

    To remove any confusion, let's also remove the comment above about the Update() function.

  11. Remove the comment // Update is called once per frame.

    void CallbackFunction(){
        
    }

    And let's add the function name to the Post() function.

  12. Continuing on to MusicEvent.Post(gameObject, (uint)CallbackType, type CallbackFunction to include the CallbackFunction as an argument.

    MusicEvent.Post(gameObject, (uint)AkCallbackType.AK_MusicSyncBar, CallbackFunction);

    Notice that a small red line appears below the CallbackFunction.

    By adding the callback function in the Post() function, the Wwise sound engine will call the callback function if it encounters one of the selected Callback Types. As you have selected the Callback Type AK_MusicSyncBar, the Wwise sound engine will call the callback function for every bar it meets in the music.

    However, the Wwise sound engine will also expect that the callback function is able to receive information about the callback notification and so your CallbackFunction needs to be able to receive that information. This means you have to declare a few variables in the function parentheses, no matter if you need it all or nothing.

  13. In the CallbackFunction() parentheses, type object in_cookie, AkCallbackType in_type, object in_info.

    void CallbackFunction(object in_cookie, AkCallbackType in_type, object in_info){
        
    }

    This will allow you to get information about the callback, like what Callback Type it is. You will not need these parameters at this moment, as you will only be receiving one callback, which is currently MusicSyncBar.

    [Tip]

    To learn more about these input properties in a Callback function, please refer to the Wwise SDK documentation.

    The callback has now successfully been set up, but we are not yet doing anything with it as the CallbackFunction() is empty. Eventually, what we need to call is each and every RhythmActions component in the game, and for this demonstration we've created a function in the GameManager that all RhythmActions components are listening to. The GameManager script is a singleton, meaning there can only exist one and it will not be destroyed during gameplay and, therefore, you can be sure the function is always available.

    When the RhythmActions script is instantiated in runtime, it will automatically create a link to the GameManager, allowing you to call all of them through the GameManager.

  14. In the CallbackFunction() function, type GameManager.PushRhythmAction();

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class PostWwiseEvent : MonoBehaviour {
        public AK.Wwise.Event MusicEvent;
        // Use this for initialization.
        void Start () {
                    MusicEvent.Post(gameObject, (uint)AkCallbackType.AK_MusicSyncBar, CallbackFunction);
        }
        void CallbackFunction(object in_cookie, AkCallbackType in_type, object in_info){
            GameManager.PushRhythmAction();
        }
    }

    Well done! You completed all script steps for this section and you can now save the script. Next, assign the Wwise-Type Event property to the Music_Region Event.

  15. In the MusicEvent property, expand Events > Music > General and double-click the Music_Region.

    You can now distribute the RhythmActions script to game objects in the Scene and, if allowed, they will move.

    [Note]

    Some game objects used throughout the world environments (Desert, Forest, and so on) are set to static. When a game object is static it cannot be moved at runtime. You can disable static on any game object, topmost in the Inspector.

  16. In the Hierarchy, select all game objects starting with TrainingArea_.

    By selecting all of these game objects and selecting Add Component, you will add the component to each object in your selection simultaneously.

  17. In the Inspector, click Add Component, then search for and select RhythmActions.

    You have now added the RhythmActions script to multiple game objects and, with the custom script, you have now engineered the callbacks into the core of the game. Let's try it out.

  18. Enter Play mode and notice that all objects that you selected are moving to the tempo of the music.

    Feel free to adjust how much the game objects are scaled and add more RhythmActions scripts to other game objects in the Scene.

The callback system is ready and working. Any game object with the RhythmActions script will be called when the Region_Music Event reaches a Music Segment bar. This is possible due to the Callback setup in the PostWwiseEvent script calling the PushRhythmAction() function in the GameManager. Compared to the previous section, this illustrates how you might have to set up callbacks by code, if you want it to be adaptable to unloading objects or simply want to more efficiently add callbacks to numerous objects.