Tutorial: Component Basics 09 — Audio Trigger Component This tutorial walks you through the steps for creating Audio Triggers and interacting with them through Lua Script for event driven reactions. You will learn how to do the following:
Create an Audio Trigger Component Lua Script Breakdown Assigning the Default ‘play’ Trigger
Prerequisites You must have the following before starting this tutorial:
Lua Script Basics Component Entities Basics Audio System Basics Existing Audio Library
Step 1: Creating an Audio Trigger Component You will need an existing Audio Library to utilize with the Audio Trigger Components in Lumberyard. For the purposes of this tutorial, ensure this Audio Library has at least a single One-Shot SFX and a single Looping SFX. Please refer to Tutorials on the Audio System for constructing and integrating your Audio Library with Lumberyard. To create an audio trigger component 1. Create a new level in Lumberyard. 2. Right click on the ground and select Create new component entity. 3. With the new Component Entity selected, open up Entity Inspector. 4. Add an Audio Trigger Component by clicking on Add Component… > Audio > Audio Trigger. a. This Component Entity will use its Lua Script Component to control not only its own Audio Trigger Component, but the Audio Trigger of another Component Entity later. 5. Add a Lua Script Component by clicking on Add Component… > Scripting > Lua Script. 6. Click on the the { } button inside the Lua Script Component to open up Wookpecker and create a new Lua file. 7. In the Save File window, name the new Lua file “tutorial_audiotrigger” and save it wherever you finding suiting.
a. We’d suggest saving this file under the /Scripts/ folder of your project directory in an effort to keep things organized. 8. With the new Lua file setup complete, go ahead and paste the following code: Source File: tutorial_audiotrigger.lua local tutorial_audiotrigger = { Properties = { CountDown = 3.0 } } function tutorial_audiotrigger:OnActivate() self.TickBus = TickBus.Connect(self, 0) self.CountDown = self.Properties.CountDown self.LoopingSFX = false end function tutorial_audiotrigger:OnTick(deltaTime, timePoint) self.CountDown = self.CountDown - deltaTime if self.CountDown < 0 then AudioTriggerComponentRequestBus.Event.ExecuteTrigger(self.entityId, "OneShotSFX") self.LoopingSFX = not self.LoopingSFX if self.LoopingSFX then AudioTriggerComponentRequestBus.Broadcast.Play() else AudioTriggerComponentRequestBus.Broadcast.Stop() end self.CountDown = self.Properties.CountDown end end function tutorial_audiotrigger:OnDeactivate() self.TickBus:Disconnect() end return tutorial_audiotrigger
9. Save the Lua Script and go back to the Entity Inspector window. 10. With the entity component we created earlier, selected, make sure the Lua Script reference is set in the Lua Script a. If the script reference is blank, click on the … button to browse for the new Lua File.
Step 2: Lua Script Breakdown In this section, we will take a look at the building blocks of the Lua Script sample provided in Step 1. Let’s get started! 1. The first thing you’ll notice is that the Script utilizes the TickBus to create a looping timer that we ping the Audio Trigger Components from. Making up the skeletal framework for our script, the code where we construct the looping timer is as follows: local tutorial_audiotrigger= { Properties = { CountDown = 3.0 } } function tutorial_audiotrigger:OnActivate() self.TickBus = TickBus.Connect(self, 0) self.Countdown = self.Properties.CountDown end function tutorial_audiotrigger:OnTick(deltaTime, timePoint) self.CountDown = self.CountDown – deltaTime if self.CountDown < 0 then self.CountDown = self.Properties.CountDown end end function tutorial_audiotrigger:OnDeactivate() self.TickBus:Disconnect() end return tutorial_audiotrigger
2. In addition to the basic looping timer variables, we also provide ourselves with the bool variable, ‘LoopingSFX’. As the name implies, we utilize this variable as a toggle to turn on and off our example Looping SFX mentioned in Step 1 of this tutorial. a. First we declare this variable in OnActivate and establish it as false: self.LoopingSFX = false
b. Then we go ahead and toggle it on and off in the same section of the looping timer (inside the OnTick Function) that we reset the countdown in: self.LoopingSFX = not self.LoopingSFX
3. Now with our framework complete, the rest of the Script is simply pinging the available functions of the Audio Trigger Component whenever our countdown runs out. The first and most useful function of the Audio Trigger is the ExecuteTrigger function: AudioTriggerComponentRequestBus.Event.ExecuteTrigger(self.entityId, "OneShotSFX")
4. After that, we utilize our LoopingSFX bool to activate the Play and Stop functions of our Audio Trigger Components. Unlike ExecuteTrigger, the Play and Stop functions will use whatever values you have typed into the actual Audio Trigger Component’s “Default ‘play’ Trigger” and “Default ‘stop’ Trigger” fields. Because of this, these functions don’t really require any specific information: if self.LoopingSFX then AudioTriggerComponentRequestBus.Broadcast.Play() else AudioTriggerComponentRequestBus.Broadcast.Stop() end
Do note that because we are using Broadcast for our Play and Stop functions. This means we will be signaling all our Audio Trigger Components to Play their “Default ‘play’ Trigger” Audio Trigger. This is primarily to demonstrate controlling Audio Controllers not immediately associated with the Component Entity that possesses the Lua Script sending out commands. a. A potential alternative to the Stop function would be KillAllTriggers and KillTrigger functions. KillAllTriggers will immediately stop all Audio Triggers being played while KillTrigger works as the inverse of ExecuteTrigger, stopping the playing of a specific AudioTrigger from an Audio Trigger Component. i. It’s important to note that the Stop function does not stop Audio Triggers who were requested from the ExecuteTrigger function. Only KillTrigger can stop those Audio Triggers. b. The Stop function doesn’t always stop the Audio playing from an Audio Trigger’s “Default ‘play’ Trigger” field. If a user inputs the name of an Audio Trigger into the “Default ‘stop’ Trigger” field, the Stop function will instead play that Audio Trigger rather than stop the “Default ‘play’ Trigger” Audio Trigger. 5. That covers all the specifics of our Lua Script and the primary ways to use Audio Trigger Components from Lua. Let’s return to Lumberyard and create one more Component Entity.
Step 3: Assigning the Default ‘play’ Trigger The final piece to this tutorial will walk you through the assignment process for Default ‘play’ Trigger, which will take our SFX loop and play it in-game as a reaction to the Lua Script events. To assign the default play trigger 1. Create a new Component entity. 2. With the new component entity selected, go to Entity Inspector. 3. Add the Audio Trigger Component by clicking in Add Component… > Audio > Audio Trigger. 4. In the Audio Trigger Component, set the Default ‘play’ Trigger value to your looping SFX Audio. a. For this tutorial, we’re using “Play_town_amb_loop” located in the tutorials_controls/ambience/ folder in the Choose Trigger… window.
5. At this point, everything should be setup and ready to run. Let’s run the Game by hitting Ctrl + G or by selecting ‘Switch to Game’ from Lumberyard’s Game tab to see things in action. You should notice that after 3 seconds (the default time in our looping timer), you’ll hear both your One-Shot SFX and your Looping SFX. This demonstrates that both your ExecuteTrigger and Play functions went off properly. The Looping SFX will then continue on for 3 more seconds while the next timer runs its course before you then hear your One-Shot SFX again and notice your Looping SFX ceasing to play, indicating your Stop function triggered successfully.
Congratulations! You have successfully created an interacted with the SFX loop through the Audio Trigger Component and Lua Script. We’d love to hear from you! Head to our Tutorial Discussion forum to share any feedback you have, including what you do or don’t like about our tutorials or new content you’d like to see in the near future.