第 8 课

目录

利用 Game Parameter 实现多样变化

我们可以使用 State(状态)和 Switch(切换开关)来在音乐环境(如当前所在区域)之间变换,同时还可利用 Game Parameter(游戏参数)来控制音乐中的微妙细节(比如,距离瀑布越近,竖琴的播放声音就越大)。我们几乎可以将任何游戏元素映射到 Game Parameter,然后选择要使用它来控制哪些 Music Track(音乐轨)或 Effect(效果器)。

Wwise 提供了很多内置的 Game Parameter(如相对于玩家的距离)。不过,这些 Game Parameter 通常更适合剧情声音(定位在游戏空间内),而音乐则大部分都是非剧情声音(游戏空间之外)。为了把 Game Parameter 直接集成到环境内的元素中,我们可以编写自定义脚本,并将 Game Parameter 映射到游戏中的元素。这样就可以把游戏中某个对象携带的定位信息提供给另一游戏对象所关联的非固定位置的声音。

接下来,我们将创建脚本并将其添加到 Waterfall(瀑布)。在此脚本中,需要创建 Wwise 专有 RTPC 属性,并为其提供从 Player 到 Waterfall 的距离。然后,将该 Game Parameter 指派给 Woodlands(林地)主题的竖琴 Music Track,使其音量随着距离增大或减小。

[备注]

注意,不要将 Wwise 中的 Distance_to_Player Game Parameter 用在 Woodlands 1_Harp Music Track 上,因为并不会针对 Waterfall_UpClose 游戏对象发送 Music_Region Event(事件)。

  1. 在 Unity 菜单栏中,依次转到 Audiokinetic > Certification > 301 > Lesson 8,然后选择 Creating Diversity using Game Parameters

    Waterfall 游戏对象本身比较大且其中心点在可行走地图之外相当远的位置,所以不好测量从实际的 Waterfall 到 Player 的距离。

    为此,我们创建了一个子游戏对象并将其放在了 Waterfall 水潭边上 (Waterfall Up Close)。这样就可以精确控制距离测量的起点。

    [技巧]

    我们将会计算从中心点(游戏对象的中心)到 Player 的距离。这样方便通过 Transform 组件检索相应的位置。

  2. 在 Hierarchy 中,展开 Waterfall 游戏对象,然后选中 Waterfall_UpClose 游戏对象。

  3. 在 Inspector 中,单击 Add Component,然后转到 New script 并将其命名为 SetRTPCToDistance,接着单击 Create and Add,最后打开脚本。

    接下来,我们先清理脚本内容。我们将会重复设置 Game Parameter,而不会使用 Start() 函数,所以下面来将其移除。

  4. 删除 Start(){} 函数以及上面的备注(// 使用此函数进行初始化。)。

     using System.Collections;
     using System.Collections.Generic;
     using UnityEngine;
    
    public class SetRTPCToDistance : MonoBehaviour {
    
        // 每帧调用 Update 函数一次。
        void Update () {
    
        }
    }

    接下来,我们先创建一个 public 类型的 Wwise 专有 RTPC 属性,并将其命名为 GameParameter。

  5. 在 SetRTPCToDistance 类之内,键入 public AK.Wwise.RTPC GameParameter;

     using System.Collections;
     using System.Collections.Generic;
     using UnityEngine;
    
    public class SetRTPCToDistance : MonoBehaviour {
        public AK.Wwise.RTPC GameParameter;
    
        // 每帧调用 Update 函数一次。
        void Update () {
    
        }
    }

    无论计算从哪个位置到此游戏对象的距离,我们都要先引用另一游戏对象的 Transform 组件。正如前面课程所讲的那样,Transform 组件包含游戏对象的位置、比例和旋转等相关信息。这样 Unity 才能依据场景中心点来放置各个游戏对象,并准确设置其大小和朝向。为了记录这些位置,Transform 组件提供了名为 Position 的 Vector3 属性。接下来,我们将使用它来监控 Player 和 Waterfall 之间的距离。

    [备注]

    Vector3 属性类型包含带有小数位的数字。它可以通过指定 X、Y 和 Z 坐标来进行定位。

    为了使脚本尽可能地通用,我们最好重复使用现有脚本,而不是另外新建一个。在此前提下,我们来创建一个 public 类型的 Transform 属性。因为会针对 Waterfall_UpClose 游戏对象运行此脚本,所以我们需要在计算距离时引用该属性中的 Player 游戏对象。另外,还要给它取个能够表明其作用的恰当名称,如 OtherTransform。

  6. 键入 public Transform OtherTransform;

    public class SetRTPCToDistance : MonoBehaviour {
        public AK.Wwise.RTPC GameParameter;
        public Transform OtherTransform;

    有了 RTPC 和 Transform 属性,便可计算 Player 和 Waterfall_UpClose Transform 之间的距离,进而将 Game Parameter 设为该距离。

    在两个不同游戏对象为 Transform 提供了相应的 Position 属性之后,可利用 Distance() 函数来计算两者之间的距离。为此,我们必须在 Update() 函数中设置此调用,以便不断更新该距离。

  7. 在 Update() 函数之内,键入 Vector3.Distance();

    // 每帧调用 Update 函数一次。
    void Update () {
        Vector3.Distance();
    }

    我们需要给 Vector3.Distance() 函数提供各个游戏对象的 Transform 位置。为此,可通过调用 Transform 组件来检索 Vector3 Position 属性。

  8. 在 Vector3.Distance() 函数的圆括号之内,键入 OtherTransform.position

    void Update () {
        Vector3.Distance(OtherTransform.position);
    }

    接下来,我们需要引用 Waterfall_UpClose 游戏对象上绑定的 Transform 组件。为了将另一 Vector3 属性发送到函数中,可直接添加一个逗点 , 并键入下一属性。

  9. 在 OtherTransform.position 之后,添加一个逗点 , 并键入 transform.position

    Vector3.Distance(OtherTransform.position, transform.position); 
     

    现在可以计算距离了,但是不会保存结果。为此,我们需要将其设为 float 变量。float 变量类型方便存储包含小数位的数值,它可以确保 RTPC 过渡流畅,而其他变量类型(如 int 或 uint)则只能存储不含小数位的数值。接下来,我们可以将 Vector3.Distance() 函数返回的结果保存在 float 变量中。具体来说,需要在 Vector3.Distance() 函数之前键入变量类型 float、名称 distance 和相等运算符 =。

  10. Vector3.Distance() 函数之前,键入 float distance =

    float distance = Vector3.Distance(OtherTransform.position, transform.position); 
     

    [技巧]

    若想进一步优化此脚本,可在 Update 函数之外创建 float distance 变量,然后只在 Update 之内设置 distance 变量。通过在 Update 函数之前声明此变量,可避免每帧创建一个新的变量。

    接下来,我们要将 Game Parameter 映射到 distance 值。为此,可使用 .SetGlobalValue() 函数来调节针对另一游戏对象触发的音乐。

  11. 在 float distance 变量和类型下面添加一个空白行,然后键入 GameParameter.SetGlobalValue(distance);

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class SetRTPCToDistance : MonoBehaviour {
        public AK.Wwise.RTPC GameParameter;
        public Transform OtherTransform;
    
        // 每帧调用 Update 函数一次。
        void Update () {
            float distance = Vector3.Distance(OtherTransform.position, transform.position);
            GameParameter.SetGlobalValue(distance);
        }
    }

    要编写的代码就这么多。接下来,我们需要在 Inspector 中指派属性。

  12. 在 Hierarchy 中,确保选中 Waterfall_UpClose 游戏对象。

  13. 在 Unity Inspector 中,转到 SetRTPCToDistance 的 Game Parameter 属性,然后依次展开 Game Parameters > Gameplay,并双击 Music_WoodlandsHarp

    在 OtherTransform 属性中,可添加游戏对象的 Transform 组件以便脚本计算相对距离。在本例中,我们将使用 Player 游戏对象。

  14. Player 游戏对象从 Hierarchy 拖到 OtherTransform 属性中。

    在进入 Play 模式之前,我们还要配置 Game Object Profiler 以便监控 Game Parameter,然后连接游戏。

  15. 在 Wwise 菜单栏中,转到 Layouts(布局),然后选择 Game Object Profiler(游戏对象性能分析器)。

  16. 在 Game Sync Monitor(游戏同步器监控器)中,单击 Add…(添加...)。

  17. 在 Project Explorer - Browser(工程资源管理器 - 浏览器)中,展开 Gameplay,然后双击 Music_WoodlandsHarp

    现在我们选择了 Game Parameter,接下来需要添加游戏对象。因为只针对 Waterfall_Up_Close 游戏对象使用了 Music_WoodlandsHarp,所以我们可以直接监控全局作用域的 Game Parameter。

  18. 在 Game Object Explorer(游戏对象资源管理器)的 Watches(监视)选项卡中,单击选择器按钮 [>>],然后选择 Global Game Object(全局游戏对象)。

    现在 Game Object Profiler 已经准备就绪。

  19. 连接游戏并进入 Play 模式。跑向 Woodlands 内的 Waterfall。

    在逐渐靠近 Waterfall 时,留意 Woodlands 主题中的竖琴声音。现在您可以退出 Play 模式了。

您有没有注意到在逐渐靠近时 Woodlands 主题的竖琴声音会慢慢变大?接下来,我们仔细看下 Wwise 监控结果。

在 Game Sync Monitor 中,我们会看到与 Waterfall_UpClose 游戏对象关联的 Music_WoodlandsHarp Game Parameter 值在逐渐减小。此值代表的是 distance。也就是说,逐渐靠近 Waterfall 时的播放行为正是我们想要的。我们只用了几行代码,就实现了让乐曲随着玩家行为不断变换的效果。假如在编写脚本时同时兼顾可重用性,甚至还可将其快速添加到场景中的很多不同对象。

[技巧]

您现在应该基本上掌握了如何灵活运用 Game Parameter,不过本课前面还提到了一个利用其控制 Music Track 的例子(即敌人音乐),不妨参考一下。在该例子中,每种类型的敌人都有一个 Game Parameter。对应音乐分层的音量会随着距离增大或减小。敌人音乐的 Game Parameter 系统更为复杂一些,并且直接集成到了 GameManager 脚本中。倘若您想具体看一下,可在 Project 视图中搜索 GameManager,然后打开 GameManager.cs 脚本,并查看 DistanceToEnemies() 协程函数。