第 4 课

目录

通过动画发送 Event

[备注]

在开始学习本节课程之前,请务必先完成前面的“利用 Wwise 专有属性发送 Event”章节。

在 Unity 中,我们可以利用 Animation Clip 来处理动画。这些片段可以是您在外部程序(如 Maya 或 3Ds Max)中创建的动画,也可以是对 Unity 中的游戏对象的直接修改。接下来,我们看下冒险家目前的构建情况。

她的模型是在 Maya 中创建的,其对应的游戏对象绑定有各种脚本,并能执行 Move、Attack 等各种动作。不过,要想把她打造得栩栩如生,我们需要她能够在攻击怪物时挥动手臂,并在按下前进按钮时挪动脚步。

那么,声音方面该如何处理呢?在 Wwise 中,我们会看到 Random Container(随机容器)中包含了一系列精心制作的脚步声。可是,如何确保在冒险家脚踏地面时准确地播放恰当的声音呢?为此,我们可以创建一个 Animation Event,并利用这一 Unity 元素来将动画内的某个时间点关联脚本中的函数。首先,我们要选择 Animation 中的某个特定时间,然后指定脚本中的函数,以此通过动画来发送 Event(事件)。接下来,我们会将之前创建的 PostWwiseEvent 改为触发玩家脚步声,同时修改 Start 函数以便通过 Animation Event 来进行调用。然后,我们会察看 Animation Editor 并直接通过 Animation Event 来调用新建的函数。

  1. 在 Unity 菜单栏中,依次转到 Audiokinetic > Certification > 301 > Lesson 4,然后选择 Posting Events from Animations

  2. 在 Hierarchy 中,选中 Player 游戏对象。

    接下来,我们将前面章节中创建的 PostWwiseEvent 添加到 Player 游戏对象(稍后我们还将在“第 5 课”中用到该脚本)。

  3. 在 Inspector 中,单击 Add Component,然后选中 PostWwiseEvent

    假如无法在工程中看到此脚本,请回顾一遍前面的“创建 Wwise 专有 Event 属性”章节。

  4. 单击 MyEvent Property Drawer,然后双击 Player_Footstep Event。

  5. 双击 PostWwiseEvent 打开脚本。

    此时,Visual Studio 或所用默认代码编辑器将会打开。在该编辑器中,我们会看到之前创建的 PostWwiseEvent 脚本。一旦进入游戏模式,此脚本中的 MyEvent.Post() 函数调用便会调用 MyEvent 属性中选中的 Event。

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class PostWwiseEvent : MonoBehaviour {
        public AK.Wwise.Event MyEvent;
        // 使用此函数进行初始化。
        void Start () {
            MyEvent.Post(gameObject);
        }
        
        // 每帧调用 Update 函数一次。
        void Update () {
        
        }
    }

    目前 MyEvent.Post() 函数调用位于 Start() 函数之内,所以会在启动游戏时发送 MyEvent 属性中选中的 Event。不过,我们现在想通过 Animation Event 来调用 Start() 函数。为此,可直接给该函数取个自定义名称,以免 Unity 在运行游戏时自动进行调用。

    [备注]

    函数的名称关系到前面的课程步骤,但对在 Unity 中使用 Animation Event 来说并不重要。您可以随意给函数另取一个名称,比如 PostFootstepEvent。不过要注意,假如该名称与 Unity API 中使用的函数相同,另一进程有可能也会调用该函数。

  6. Start 替换为 PlayFootstepSound

    public class PostWwiseEvent : MonoBehaviour {
        public AK.Wwise.Event MyEvent;
        // 使用此函数进行初始化。
        void PlayFootstepSound() {
            MyEvent.Post(gameObject);
        }

    之前脚本的 Start() 函数会在进入 Play 模式时调用。不过现在我们进行了重命名,Unity 不会再在场景加载时自动调用该函数中的内容了。在开始创建 Animation Event 之前,我们需要在声明函数前添加 public 访问修饰符,来允许 Unity 查看刚才命名的函数。

  7. void PlayFootstepSound() 之前,插入 public

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
        
    public class PostWwiseEvent : MonoBehaviour {
        public AK.Wwise.Event MyEvent;
        // 使用此函数进行初始化。
        public void PlayFootstepSound() {
            MyEvent.Post(gameObject);
        }
    }

    现在,我们将 PlayFootstepSound() 函数的访问修饰符设成了 public,脚本算是完成了。

  8. 按下 CTRL+S(在 Windows 上)或 CMD+S(在 Mac 上),以便保存脚本

    接下来,我们返回 Unity 并创建 Animation Event。因为需要将 Animation Event 添加到 Player,所以我们先来选中 Player 游戏对象。

  9. 在 Hierarchy 中,确保选中 Player 游戏对象。

    为了添加 Animation Event,我们需要打开 Animation 窗口。

  10. 在 Unity 菜单栏中,转到 Window 并选择 Animation

    此时将会显示 Animation 窗口。在此,我们可以修改动画的设置。假如这是您第一次打开 Animation 窗口,有可能会将其显示在单独的窗口中。在仔细查看所含内容之前,我们先来调节一下窗口,使其与布局的其余部分相称。

  11. 按住 Animation 选项卡并将窗口拖到 Unity Project 视图的右侧。

    在 Hierarchy 中选中 Player 游戏对象的情况下,Animation 窗口将会显示 Player_Idle_wHammer Animation Clip。

    利用 Animation Clip,我们可以存储属性中的一系列修改。窗口的左侧窗格中会列出所有属性。在右侧窗格中,我们会看到一系列的属性修改点。这些点称为关键帧。在关键帧之上、时间线(顶部时间条)之下,我们会看到 Event 行。在此,我们可以添加 Animation Event。在白色时间光标到达某个 Animation Event 时,将会调用指派的函数。这样就可以确保在 Animation Clip 中的特定时间有动作被调用。接下来,我们要在 Player 脚踏地面时调用 PlayFootstepSound() 函数。为了便于展示,我们来使用 Player_Sprint Animation Clip。

  12. 若要查看 Player 使用的所有 Animation Clip,请打开左上角的列表菜单。

    在此,我们会看到 Player 的动画系统使用的所有 Animation Clip(由 Animator 组件管理)。

  13. 在左上角列表中,选中 Player_Sprint

    在左侧窗格中,可看到动画当中修改的组件;在右侧窗格中,可看到时间线以及下方的 Event 行。

    在时间线的最左侧,我们会看到从顶部一直延伸到底部的白色时间光标。这条线用来指示 Animation 中的当前时间。在时间线中通过拖动或单击来改变它的位置时,将会根据 Scene 视图中 Animation Clip 的对应时间调整冒险家的动作。

    我们注意到,目前将冒险家设到了 Player_Sprint Animation Clip。在左右拖动时间光标时,我们会看到冒险家也会随之迈出左脚和右脚。

  14. 在时间线中,来回拖动时间光标。

    假如视图中混杂了各种符号和文本,可在 Scene 视图的 Gizmos 选项卡中移除其中的大部分内容。n

  15. 在 Scene 视图中,转到 Gizmos 选项卡,然后取消选中 3D Icons

    接下来,我们得找到要在动画中开始播放声音的确切时间点。

  16. 拖动时间光标,直到冒险家将右脚踏在地面上 (0:05)。

    在此,我们将添加 Animation Event,稍后还会指派给 PlayFootstepSound() 函数。

  17. 在 Event 行中,右键单击时间光标 (0:05),然后选择 Add Animation Event

    我们注意到,Event 行中出现了一个新的 Animation Event 标记。

    为了确保时机准确无误,请仔细检查 Animation Event 标记是否刚好落在 0:05 位置,否则会跟 Scene 视图中看到的画面不一致。接下来,我们仔细看下 Inspector。

    在此,我们可以添加要在时间线中选定的时间点调用的函数。该操作可通过本节前面添加的 public 访问修饰符来实现。

    [技巧]

    注意,Animation Event 只能关联到 Animator 组件所管理的同一游戏对象上添加的函数。假如您想关联到另一游戏对象上应用的脚本,必须另外编写脚本来转发函数调用。

  18. 单击 Function Property Drawer,然后选择 PlayFootstepSound() 函数。

    现在,我们将函数关联到了 Animation Event 标记,接下来即可测试声音效果。

    [技巧]

    Function 列表中包含的内容比较多,不过您可以通过键入函数名称的首字母(本例中为 P)来快速找到需要的函数。

  19. 进入 Play 模式(如“第 1 课”所述),然后在按住 Shift 的同时按下 W 来快速奔跑。

    现在,我们为右脚添加了 Animation Event。接下来,我们要为左脚添加。退出 Play 模式,然后返回 Animation 窗口。

  20. 拖动时间光标,直到看到左脚踏在地面上 (0:15)。

  21. 在 Event 行中,右键单击时间光标,然后选择 Add Animation Event

    [技巧]

    除此之外,您也可以通过单击 Event 行左侧的 Add Event 按钮来添加 Animation Event。此操作会在时间光标当前所在位置添加 Animation Event。

  22. 在 Inspector 中,选择 PlayFootstepSound() 函数。

  23. 单击 Play 按钮,并在场景中四处跑动。

    在 Training Area(训练场)内四处跑动,同时试听脚步声效果。我们注意到,脚步声会随着 Player 动作流畅地播放。通过直接将声音关联到动画,我们确保了只在 Player 执行相应动作时播放脚步声。您可以按照本节练习中的相同步骤,来将脚步声集成到步行、攻击等各种动画中。

    接下来,我们要把更改保存到 Player Prefab 中,以便稍后在“第 5 课”中使用。

  24. 按下 ESC 打开《WAG》游戏菜单,然后再次单击 Play 按钮退出 Play 模式。

  25. 选中 Player 游戏对象,然后在 Inspector 中单击 Apply

    现在,工程中的所有 Player 游戏对象都会将相同的脚步声行为关联到动画。