Download

Possible to blend between two different sounds in AudioComponent.uc?

Currently I blend between sounds by having multiple AudioComponents and fading one in while the other fades out.

Is there anyway to achieve this with single audio component?

I made a class that fades into the next song by calling AudioComponent.FadeOut(), changing AudioComponent.SoundCue, and then calling AudioComponent.FadeIn(). I’m 99% sure there’s no way to just do a direct crossfade of playing both SoundCues at the same time using just one AudioComponent. You’re already doing it the best way possible using just UScript. I think if you want a fancier solution, you’ll have to use Wwise or something similar.

It’s been a while since I’ve mucked around in dynamically controlling sound cues, but if you already know all of the sounds you’ll want to use, you can load them all into the same SoundCue, and give that SoundCue some Continuous Modulator nodes. Then in UScript, control the Continuous Modulator nodes to blend in the desired sounds.

Nice idea about simply controlling nodes in the soundcue. Thanks for the suggestion :wink:

@Nathaniel3W How are you accessing the sound nodes in the soundcue via unrealscript?

I don’t see any method in SoundCue.uc to access the individual nodes. Did you just create your own method to recursively look through ChildNodes for each SoundNode, starting from FirstNode?

Also, how do you tag a node with a parameter name (as you may have many modulator nodes in a soundcue node tree)?

Hey there Coldscooter. I just now read through this whole post and I remembered that I did what I described above in a different project. It may take me a while to dig it up. For now let me just copy/paste what I’m doing now (which is a lot simpler than what we discussed above). I’ll go see if I can find that old project. (I mentioned it in another post. It was using the motion controller to teach youth at church how to conduct music.)

I’m doing a few different things to mix sound together. First, I give my pawns two audio controllers so that they can play two sounds at once:



class MyPawn extends Pawn;

var AudioComponent AC, AC2;

DefaultProperties
{
    Begin Object Class=AudioComponent Name=MyAudioComponent
        bUseOwnerLocation=true
        bAutoPlay=false
        bAutoDestroy=false
    End Object
    Components.Add(MyAudioComponent)
    AC=MyAudioComponent

    Begin Object Class=AudioComponent Name=MyAudioComponent2
        bUseOwnerLocation=true
        bAutoPlay=false
        bAutoDestroy=false
    End Object
    Components.Add(MyAudioComponent2)
    AC2=MyAudioComponent2
}


Then when I want them to play a sound,



function PlayASound(SoundCue SoundCue)
{
    if(!AC.IsPlaying())
    {
                    AC.SoundCue = SoundCue;
                    AC.Play();
    }
    else
    {
                    AC2.SoundCue = SoundCue;
                    AC2.Play();
    }
}


So that’s for pawns playing two sounds at once. In order to fade music in and out, I wrote this class, and put an instance of it in my PlayerController. Without too much effort, you could give this class two audio components and fade one in while the other fades out so there’s a little bit of overlap between the sounds.



//=============================================================================
// Copyright 2017-2018 Rockwell Studios, LLC. All Rights Reserved.
//=============================================================================

class RPGTacSoundFader extends Actor;

var AudioComponent AC;
var SoundCue NextSong;

event PostBeginPlay()
{
    AC = new class'AudioComponent';
}

auto state Waiting
{
    event Tick(float DeltaTime)
    {
    }
}

state FadingOut
{
    event Tick(float DeltaTime)
    {
        if(!AC.IsPlaying())
        {
            if(NextSong != none)
            {
                AC.SoundCue = NextSong;
                FadeIn();
                NextSong = none;
            }
            GotoState('Waiting');
        }
    }
}

function LoadNewSong(SoundCue NewSong)
{
    if(AC.IsPlaying())
    {
        NextSong = NewSong;
        FadeOut();
    }
    else
    {
        AC.SoundCue = NewSong;
        FadeIn();
    }
}

function FadeIn()
{
    AC.FadeIn(2.0, 1.0);
}

function FadeOut()
{
    GotoState('FadingOut');
    AC.FadeOut(2.0, 0.0);
}

event Destroyed()
{
    AC.Stop();
    AC = none;
    NextSong = none;
}

DefaultProperties
{
}


I think I must have only worked with one continuous modulator at a time in the project I mentioned above. I must have found that one continuous modulator and tweaked its pitch to slow down or catch up to the conductor. I know I didn’t go any deeper than that, but I think this is how you would do it:

In SoundCue, there is a SoundNode variable called FirstNode. All SoundNodes have an array of SoundNodes called ChildNodes. If you give your SoundNode class a name variable, then you can iterate through all of the sound nodes in ChildNodes, and see if the name matches the name you’re looking for. And if so, see if SoundNodeMixer(SoundNode) != none, and then change the appropriate entry in its InputVolume array.

Edit: I’d be very interested in hearing if you can get this to work. Please update the post when you have more to tell us.

I use fade in and fade out functions to probably irrelevant but wanted to participate in the discussion : P.