Setting Metasounds Variable

I played with delayed variables but could not figure out the intent. Thanks for the example, I’ll renew the effort on that because that would solve a months worth of pain. My graphs were getting to the point where I could not follow what I’d done with so many triggers. A cursory look suggests what you are showing there might wipe out a bunch of superfluous triggers in my now indecipherable MS music manager.

Your comment to Jabbinuz also clears up why my first cut (using Play Quantized) did not work. I shifted to Spawn to start the MS and then let it do all the playing and keeping the meter/measure. That may work now with this delayed concept.

Explanation of misinformed comment deleted here

I can’t stress how much I appreciate you providing knowledgable insight into our issues.

Not a problem! But ya, the main goal of GetDelayed is to help work around cycles - it delays by exactly one frame. Iirc I don’t think the official docs are updated to include the MetaSound stuff that’s been added since EA :sweat_smile:, but I think there’s a KB article hanging around with more info on the new stuff.

I promise, we really are working on making info about how things work more discoverable.

1 Like

Thanks very much, you’ve been a great help. I will work with my MS and check out this feature.

The delayed variable worked.

yes exactly same voices. Anyway, assuming it is not advisable to mix the 2 systems, I wonder how to share the same clock in a reliable way between different MS which are spatialized. Thank you in any case, and yes, some info would be really helpful! thanks!

Technically it delays one block not one frame.

We use frame in UE to describe a single time-slice of audio (i.e. 1/48,000 of a second if you’re rendering at 48,000 frames per second). Note I used “frames per second” to be overly precise since “sample” would be the individual audio value that would sent to a given channel – i.e. a frame of stereo audio is two samples. Although Samples Per Second is the “sample rate” used to describe audio usually, it’s almost always intended to mean channel-independent frame rate.

We use the term “block” to describe the array of frames we render per audio rendering segment and, for MetaSounds, that’s 100 frames per second (so 480 frames in one block at 48k).

How are you making the ‘delayed get’ of a variable, the set in the pink box? And how does that relate to ‘NumToPlay’ ?

There are little to no video’s explaining these details, and it really helps noobs like me to see the step by step process. Your blueprint is helpful, yet the solution isn’t crystal clear.

My personal goal is to have a loop play a set number of times, determined randomly … and then start a new loop from the array.

Just in case she’s busy…

  1. The delayed variable is created by grabbing the variable from the lefthand details panel for variables, dragging it into the graph, then releasing it while holding alt (option on the Mac). That will drop the delayed version of the variable into the graph.

  2. NumToPlay is an input type variable either set by the calling blueprint with Set Int Parameter or taking the default value as set up initially. It relates to the delayed variable as the reset or rather, the number of times the delayed variable will be set causing the wave to be selected before it goes to the OnFinished and quits. So NumToPlay would be the number of waves you want to trigger through to play a wave. If it were 5, you would select 5 random waves to play, then stop.

Hopefully she’ll correct any mistakes I have in this. That graph she posted stopped weeks of floundering for me. Delayed variables are very important.

2 Likes

Thank you, that helps point me in the right direction.

I’ve followed this tutorial : How to Use MetaSound Presets | Tutorial

And the preset works when inside the preset, but it doesn’t work in the main metasound.

However, if I don’t use presets and just make it an actual array, it works.

Yet I have yet to figure out how to add multiple files that will play and loop.

Off the top of my head, it seems you will need a trigger counter to play the selected loop for a random number of times, its reset would be fed from a random int. The wave player onplay would be fed from the trigger counter output and it’s onnearlyfinished would have a trigger variable output which would feed into the trigger counter as a delayed variable. When the trigger counter resets, you would feed the reset pin into an array get that has random int feeding its index. It’s more complex than that but maybe the right principle.

All great in theory, and nothing is working.

I’m not even able to have presets work inside this graph to help trouble shoot.

When I make it an array, it works. At least, it plays a loop. And that’s it.

Otherwise, it doesn’t work. And I’d rather use presets b/c it seems to be the best approach. Yet it won’t let me drag and drop the preset into the graph, nor does there seem to be any way to add them.

The only way I can get them to work is to place them inside the scene and on the map level and hit play. I’m not sure if its supposed to even work like that, the directions for metasounds and presets are lacking.

Pretty much at a total loss at how to proceed. UE4 has a plethora of tutorials and years of video’s showing ‘how-to’, and UE5 isn’t there yet. So much has changed.

I was able to get presets to work for my footsteps and it was pretty convenient. I did the following:

  1. Create MetaSoundSource with all graph code necessary and Input Variables/Arrays
  2. Right click on that in content browser and select Create MetaSound Preset (at the top of the menu)
  3. After doing that for each type of footstep, I modified each preset to have the footstep arrays for the waves in that category (e.g., snow, gravel, grass, wood, metal etc).
  4. When a footstep is required, I select the specific preset as the sound based on physical surfaces (this came from a tutorial which I can look up if you need, it was totally based on presets).

Would you mind posting that blueprint? While Im not making footprints, its my hope that seeing your work will give me a clue or two. :slight_smile:

And the link for the tutorials you’ve followed would be helpful as well.

I’m not clear on how to do the delayed variable. I was able to add a delayed variable (thank you for the keytip), I’m not sure how to implement it with everything else.

This won’t be useful on the issue of delayed variables because footfalls don’t need them. I may have another example I’ll post below on the use of those but I don’t think it will add to the graph posted above.

For Footfalls, go through this tutorial and the one it mentions at the top prior to doing so. This tutorial will let you set up your Physics surfaces and create a TMap that will let you fire a ray down to where the player is walking and return the correct metasoundpreset / metatsoundsource to play. We took this a little further and did this from the animblueprint of AIs using animnotifies. Players we handle separately so the footsteps aren’t counted in the channel list (it saves a channel to have players footsteps included in a 2d sound manager MetaSound).

You asked for the footstep blueprint and presets so here they are. There is nothing particularly interesting in them. The first two are what is used from animblueprints for the AIs, the third leverages those in a rather clunky way so players footsteps are incorporated in my 2d sound manager.

Basic Footfall MetaSoundSource, this serves as the template for the presets:

Example Preset for Footfalls. This one is grass. We set 6 waves in an array and randomly pick which to play when this gets triggered by the animnotify in animblueprint. You can see it’s using the above basic MetaSoundSource. It was generated by right click in content browser on the above MSSource and selecting to create a preset. The only thing referenced when using it are the presets. If you set up presets things like this, be sure to include an Attentuation class, a submix class, and you may want to put a priority and limit concurrency for the presets involved. These are under the Source button (thanks to the forum user who told me to look there).

As I mentioned, player is handled differently and there was no elegant way to do it other than have a set of enums which are used when it’s called. The only interesting thing is that I use the AI’s footfall presets in this MetaSoundSource so I automatically get the right waves for the enum. In this case, Snow is 0, Grass 1 etc. Ignore the stuff to the right, that is for players weapon sounds which again are included in the 2D manager to save channels. What is nice is I can just change the top graph if I want to alter how the footsteps work and both AIs and Player will automatically be impacted.

As to the delayed variable question, here is a few places I’m using it. It was a life saver. I think the example @lantz.anna_1 posted is superior to show the same thing because it’s clean and this is a mess, but this shows how complex use can do many different things. If you see the bottom right variable LoopDone, it’s set by OnNearlyFinished, which when used in the upper left corner, starts things to play the next CombatLoop (the line running down to the bottom left). Suffice it to say, when you try to connect a pin and it refuses to let you due to a loop, that is most likely where you want to use a delayed trigger variable.

BTW, this is way more complex than most people would care to use. It’s so complex because it toggles between idle and combat playing an idle intro and multiple idle themes and a combat intro and multiple combat themes and moves between them on even measures. That’s usually not important to people. It’s also not doing random selection of themes, they are composed to play sequentially. This isn’t a graph to be proud of :wink:. The way I should have done it is compose the intros so they and the themes were one long loop. Most games seem to do this and just start the idle or combat over in their entirety. That would be a cleaner approach.

This probably should be it’s own thread. :wink:.

2 Likes

Out of curiosity, what exactly do you mean by “Preset works when inside the preset, but doesn’t work in the main metasound”? It might help to know what things would be useful to add or clarify in that tutorial.

But on the general topic of Delayed Get - it looks like based on your further comments you figured how to access it but aren’t sure how to use it. So at least in the context of the original post, I use it so the play trigger doesn’t cause a loop. But before I even get into that - how familiar are you with the Trigger Counter node? That’s usually the important one when making loops.

In case you haven’t worked with Trigger Counter much: what it does is count the number of times it gets triggered, but you can tell it to “restart” after a certain amount of triggers. That’s what the Reset Count field is - when that field is nonzero, its interpreted kind of like “after I do the thing On Trigger is attached to NumToPlay amount of times, then I should do what On Restart is attached to.”

In the context of my MetaSound, this basically turns into “after playing NumToPlay waves, I should say the MetaSound is finished playing.” But there’s no reason you couldn’t connect them so that, say, On Trigger goes to “play the same sound” and On Restart goes to “select a different sound to loop.” And you can put a random number or whatever you like in the Reset Count field.

So coming back to the GetDelayed thing. When you’re playing multiple soundwaves after one another, you’re going to need a way to know when the next soundwave should start. If you just connect On Finished back to Play, the MetaSound Editor will start yelling at you about infinite loops. But the “On Nearly Finished” node on the Wave Player gets called one block before the wave finishes, which is incidentally the length of time it takes to Get Delayed back. So you can use this to concatenate stuff.

I.e., this would just play the same sound over and over indefinitely:

And this play the same sound a random number of times, then stop:

And this will play the same sound a random number of times, and then select a different sound from the array to play that number of time, ad infinitum:

5 Likes

Outstanding response, thank you for taking the time to explain all of it! Off to decipher and understand it all. :smiley:

Shouldn’t ‘wavtouse’ be an array?

When I pull out from ‘value’ on the randomget, it gives me two options for variables, I selected ‘promote to graph variable’ and turned it into an array, and it won’t connect.

When I pull out from ‘value’ and use ‘set wave asset array’, I end up with something different than you are showing. I’m also not able to use the alt function to get a delay like you have with WavToUse going into the wave asset on the wave player.

WaveToUse doesn’t need to be an array (and actually, can’t be an array if you want it to run the Wave Player). . . but you’ll probably need to add an array input of some kind. I.e., the array should go into the “In Array” slot. RandomGet is basically “picks one value from an array,” so ya it’s an individual asset.

Which is probably also why “Set Wave Asset Array” isn’t doing what you want, it sets one index in your array with the given value. (We really need our node reference doc to be public again. . .)

So the Wave Player node always expects exactly one wave, so things like walking through arrays you’ve got to implement yourself. That’s actually another really common use case for Trigger Counter! So something like this will play through every index in the array, in order, then stop.

If you want to randomize the array after a few iterations, I’d take a look at Shuffle (WaveAsset::Array) as a node.

(I’m thinking the inability to find Get Delayed might have been a side-effect of making your variable an Array, but if not let me know, that might be a bug.)

I am so lost.

So I made a graph variable called ArrayIndex, and its an Int32. is there something else to do with it?

Both of these … make sound. There is no randomization happening nor changes being incurred. I tried it with both random get wave and get wave array.

With no Random

With Random

OnNearlyFinished is a trigger.

Different question for you - what did you expect to happen in these MetaSound graphs?

So like, at a glance in the first one. If the Trigger Counter’s “On Trigger” is connected to On Finished, that tells the MetaSound to stop playing once that Trigger Counter is hit, once. So I’m guessing it’s playing the first sound exactly once and ending, ya? So what you’re going to want to do is only connect that On Finished pin if there’s an event that you want to signal the end the MetaSound, like you would if, say, using your MetaSound as a one-shot. If it’s a MetaSound you expect to loop until you manually stop it, you don’t need to connect to On Finished at all - if you want to get rid of it, you can take out the One-Shot Interface in the lefthand side of your screen. If you do have a time where the MetaSound is considered done playing, connect that to On Finished instead of the Trigger Counter’s On Trigger.

If you get rid of the connection to On Finished, then the first MetaSound should walk through the array, in order. It doesn’t have any randomness because no randomness was added via any node.

Same thing with the second one, re: On Finished - that’s telling the MetaSound to stop playing after Trigger Counter gets hit, which it will once your Wave Player finishes playing it’s first sound. (There are some notes on what each node should do if you hover over it - those should help. If any of them are super unclear, let me know, I can change the tooltips)

Though at a glance the second one will, also not do what you want. Are you familiar with Seeds? The short version is “seed” gives it kinda, well, predictable randomness. It’s normally used if people, for example, wants a MetaSound to randomly choose 4 notes, and then to repeat those same 4 notes when “Reset” is hit. Changing the seed via something like Array Index does not do much useful, but if you want it to select a random sequence of Waves and then repeat the same pattern, what you do is set Seed to a single positive value, and trigger “Reset” once you want the pattern to start repeating.

1 Like

This is almost there, thank you for the explanations, it really helps. Have you written any tutorials for Metasounds? You’d be great at it.

Removing ‘OnFinished’ made this head in the right direction.

How do I have it play X number of times, chosen from an array? EG, the files are short loops and I’d like to have them loop 10 times, or 20 times, or 30 times, etc.

This works and shuffles, yet the file plays once, and moves to the next file. It plays everything in the array. My preference would be for a random file to be played. Hence the next blueprint.

This works, yet alternates between two files and doesn’t use any of the others in the array.