#Sounds stuff

1 messages · Page 1 of 1 (latest)

past dagger
#

That was the name

#

Darn

#

Sounds stuff

#

"So could I assign the names the same way as I do now in the inspector or not?"

tired lava
#

You wouldn't need to use any names, that's the beauty of it. You just reference these assets in scripts, just like you would reference an AudioClip directly

past dagger
#

Because the end goal is making it easy to use for my teammates mostly

tired lava
#

This is like an AudioClip but with extra data

past dagger
#

Hmmmm

tired lava
#

The AudioManager doesn't need to find anything, it just gets this SoundAsset and it can directly access its audio clip and related data

past dagger
#

If someone wants to add another sound, how would someone go about doing that

#

Because currently it's just an easy drag and drop

#

At the clip

#

thing

tired lava
#

It's basically exactly the same thing, except instead of pressing that + in the AudioManager, you'd create a SoundAsset in a project folder.

#

Then you fill in the exact same data

past dagger
#

Does it add to the SoundAsset or will it be each an independant file?

#

Also I read the text wrong

tired lava
#

Each SoundAsset will be an independent file/asset

#

Which you reference from scripts instead of using a hardcoded name

past dagger
#

But if I understand it right with the method you're suggesting there would be no interaction with the inspector, correct?

tired lava
#

Not with AudioManager, but each SoundAsset has its own data with its own inspector

#

You select the asset and you edit its properties

#

Which are the same properties as in this Sound class from Brackey's

#

An audio clip, volume, pitch and loop

past dagger
#

Right

#

So would that be on these files itself?

tired lava
#

You can't attach extra data on these source audio files, so you have to make a new asset type that wraps around the audio clip and includes the extra data

past dagger
#

Sorry that I'm taking up all of your time, I'm just having a hard time to paint a picture of what you're suggesting

tired lava
#

Maybe it's easier if you have the scripts so you can see what it looks like in the editor

#

If you post your AudioManager script, I can edit it to this new workflow.

past dagger
#

You want the file or just the code?

tired lava
#

Just the code is fine

past dagger
#
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AudioManager : MonoBehaviour
{
    public static AudioManager sound;
    public Sound[] sounds;
    private bool cooldown;

    [SerializeField]
    public enum Name
    {
        yes,
        no
    }
    public Name name1;

    private void Awake()
    {
        DontDestroyOnLoad(gameObject);

        if (sound == null)
            sound = this;
        else
        {
            Destroy(gameObject);
            return;
        }

        foreach (Sound s in sounds)
        {
            s.source = gameObject.AddComponent<AudioSource>();
            s.source.clip = s.clip;
            s.source.volume = s.volume;
            s.source.pitch = s.pitch;
        }
    }

    public void Play(string name, bool overlap = true, float delay = 0)
    {
        Sound s = Array.Find(sounds, sound => sound.name == name);
        if (s == null)
        {
            Debug.LogWarning($"Sound {name} not found");
            return;
        }

        if (overlap)
            s.source.Play();
        else if (!s.source.isPlaying && !cooldown)
        {
            s.source.Play();
            StartCoroutine(Cooldown(delay));
        }
    }

    public float SoundDuration(string name)
    {
        Sound s = Array.Find(sounds, sound => sound.name == name);
        return s.source.clip.length;
    }

    private IEnumerator Cooldown(float delay)
    {
        cooldown = true;
        yield return new WaitForSeconds(delay);
        cooldown = false;
    }

    public void Stop(string name)
    {
        Sound s = Array.Find(sounds, sound => sound.name == name);
        s.source.Stop();
    }
}
#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

[Serializable]
public class Sound
{
    public string name;

    public AudioClip clip;

    [Range(0f, 1)]
    public float volume;
    [Range(0.1f, 3)]
    public float pitch;

    public bool loop;

    [HideInInspector]
    public AudioSource source;
}
#

Those are the only 2 classes I use

#

Also tysm for all the help :)

tired lava
#

I want to suggest another improvement. You have this Stop(string name) method, but this means that you can only have one sound of each type playing at once. Like, you can't play two Charge sound effects. Is that not an annoying limitation?

past dagger
#

I've not run into that yet due to me not having used it much

#

So I don't really know the limitations :P

tired lava
#

I think it's a bit yucky, but I'll keep that functionality the same for this conversion

past dagger
#

I honestly don't get how the Stop affects that only 1 can play at the same time

#

Or do you mean if you stop one

#

That it stops them all

#

In which case yes

tired lava
#

But you can see the Stop method only finds one Sound and stops that

#

So that's weird

past dagger
#

Yeah it's not supposed to stop all sounds if you mean that

tired lava
#

I know, but what if you have two Charge sounds playing? Which one does it stop?

past dagger
#

I don't know?

#

Haven't run into a situation where 2 of the same sounds play at once that I also am stopping

tired lava
#

But can you even play one sound overlapping? There's one audio source for each sound, so it can't play the same sound multiple times

past dagger
#

It can I think

#

Well

#

Sort of

#

It resets the old one yes

tired lava
#

That's pretty limiting

past dagger
#

I guess so?

#

I'd have probably hit that wall if I were further with using sounds

#

I just like perfecting things even though I have barely used it lmao

tired lava
past dagger
#

Why is one hastebin and the other hatebin lmao

tired lava
#

Because hastebin rate limited me for trying to upload to quickly

past dagger
#

Interesting lol

tired lava
#

And here's an example of how this would be used in scripts:

public class Player : MonoBehaviour
{
    [SerializeField]
    private SoundAsset jumpSound;

    private void Jump()
    {
        AudioManager.sound.Play(jumpSound);
    }
}
#

And in the inspector you'd drag in the sound asset you want Player to play when he jumps

past dagger
#

How do I create the scriptable object in the assets?

#

Or do I not have to do that

#

Should probably mention this is my first time working with scriptable objects 😅

tired lava
#

You do, and it will appear as an option under Create when you right click in a folder

past dagger
#

I've heard of them before and seen a bit

#

but that's it

tired lava
#

Looks like you have a compile error

#

That will prevent the new code from compiling

past dagger
#

Yeah was thinking about that

tired lava
#

I'm assuming it's from scripts that are using the AudioManager. You can just comment out those lines for now.

past dagger
#

Exactly what I just did

tired lava
#

There it is

past dagger
#

Alright im blind then

tired lava
#

First item

#

"Sound Asset"

past dagger
#

Yup just saw that lol

tired lava
#

The name you give the file doesn't matter because you won't use that name anywhere in the code

past dagger
#

Got it

#

Hang on, it just finds any audio source within assets?

#

No matter the foldering?

past dagger
tired lava
#

You mean the list you pick from when assigning the audio clip?

past dagger
#

ye

tired lava
#

Yeah, it doesn't organize it

past dagger
#

Well it's amazing though that it just looks for all audio and just puts in that convenient list

#

Okay so for each sound, I need another scriptable object right?

tired lava
#

Yep

past dagger
#

Which would just be Create > Sound Asset

tired lava
#

Yep

#

Same as the first one

past dagger
#

Wait I no longer need to find an array

#

eg this

tired lava
#

Exactly. That would be slow.

past dagger
#

Wow

#

Sorry I'm trying to process all of this lmfao

past dagger
tired lava
#

You define it as a serialized field so that you can select which audio you want it to play from the inspector

#

It's more work than just hardcoding it, but it means that you can easily swap to a different sound, even during playmode testing.

#

And you avoid any hard coded references, which is always good

past dagger
#

But that would mean audio would be assigned per object

tired lava
#

So my Player Jump example would look like this

past dagger
#

Instead of just being accesible from everywhere

past dagger
tired lava
#

You can still think of it as accessible from everywhere, but instead of choosing what sound you play from code, you're choosing it from the inspector

#

You can reference any sound asset in any script

past dagger
#

Hmmm

#

So if some object were to have 5 different sounds

#

I'd have to define all 5 at the top?

#

Instead of just being able to use them without having to define them

tired lava
#

Yes. I can understand if you think that's too verbose.

#

But shorter code isn't always better code

past dagger
#

True

#

I just find it mostly inconvenient for my teammates

#

It isn't really hard

tired lava
#

And look, here's your enum that can be added to

#

It's just in the editor instead of in code

past dagger
#

that's pretty neat

#

Is there no convenient way though to define it in the code without having to define it in the code

#

If that makes any sense

#

Oh wait no im being dumb

tired lava
#

Then you're back where you started, getting them by string name and searching for them

past dagger
#

Which is horribly inefficient I suppose?

tired lava
#

It can be improved by using a Dictionary instead of an array.

past dagger
#

Besides just being inconvenient

tired lava
#

There's no trivial way to get an auto-complete list of the sounds available in code. The asset selector window above is as close as you can get to that.

past dagger
#

Hm

#

Is there some sort of component or script that I can just attach to an object that stores the sound effects that it needs

#

And then other script on that component can use it or whatever

tired lava
#

You can reduce the amount of code by defining all the sound assets in one line:

[SerializeField]
private SoundAsset jumpSound, chargeSound, attackSound;
past dagger
#

Yeah I knew that, but thanks

tired lava
#

Are you also trying to avoid having to select the sound asset?

past dagger
#

I'm trying to avoid my teammates having to put [SerializeField] private SoundAsset soundAsset in the code

#

Any way you can just drag something on it that does that lmao

#

supreme laziness

tired lava
#

I think this will actually be better for lazy teammates. They don't have to memorize the names of sounds or check when they've forgotten, and they can't accidentally write a typo

#

That's a lot of pros for the cost of one line

past dagger
#

Also thanks a lot for all the help, again

#

I wonder, do you use this sort of system for your own games or?

tired lava
#

I do, but I call them AudioAsset

#

But basically the same thing

past dagger
#

Ah

#

Smartly coded

tired lava
#

And I have a few extra settings on them

past dagger
#

Sure, I could add those later probably if I'd want to

tired lava
#

And a custom inspector to make it easier to work with

past dagger
#

For now this is fine though I think

past dagger
tired lava
#

Well, a custom editor for AudioAsset specifically

past dagger
#

Damn

#

Impressive

tired lava
#

It's a feature Unity has, you can make custom editor GUI for specific types

past dagger
#

Is it a lot of code or?

#

Like was it hard to make

tired lava
#

Doesn't have to be. Depends how complicated you want it to be.

past dagger
#

I mean, you quite seem to know what you're doing so probably wouldn't have taken you long

#

Also this is by no means asking you to do it for me, I'm just curious how long it took you to make etc lol

#

What you gave me is plenty, and I am ever so grateful of it

tired lava
#

Here's how my AudioAsset looks like

past dagger
#

Yo that's mad

tired lava
#

This took a few days for all the features

past dagger
#

Probably

#

Seems quite rewarding in the end though

#

Very useful it seems

tired lava
#

Definitely

past dagger
#

Problem, it's not finding the scriptable objects?

tired lava
#

That's pretty weird

#

What happens if you click that crossed out eye in the top right corner?

past dagger
#

Absolutely nothing

tired lava
#

Are you able to drag and drop the asset onto the variable?

past dagger
#

Except becoming dark grey instead of light grey, so it enables and disables but doesn't do anything

past dagger
tired lava
#

Sounds like maybe the file name is still just Sound?

#

The file name must match the class name

#

So it must be SoundAsset.cs

past dagger
#

The file name of each scriptable object?

tired lava
#

No, the file name of the C# script file that contains the SoundAsset class definition

past dagger
#

Eh?

tired lava
#

Whatever .cs file you wrote public class SoundAsset : ScriptableObject etc

#

It must be named SoundAsset.cs

#

Or just SoundAsset in Unity

past dagger
#

So this is supposed to be called SoundAsset

tired lava
#

Yes

past dagger
tired lava
#

Did the project recompile after you renamed it?

past dagger
#

I assume it did?

tired lava
#

Maybe try just making a non-change in any script, like adding a space somewhere

#

To force it to recompile

past dagger
#

I've no idea what I'm doing wrong

#

But I'm fkin something up alright

tired lava
#

The SoundAsset class is definitely defined inside that SoundAsset script file?

#

It's not some other class in there?

past dagger
tired lava
#

hmm

#

Try restarting Unity

past dagger
#

Can do

#

Now it just doesn't do anything when you drag it in lol

tired lava
#

And the list is still empty?

past dagger
#

If you mean this list then yes

tired lava
#

Maybe the assets you've already made are somehow corrupt because of the wrong file name

#

Try making a new Sound Asset

past dagger
#

;-;

#

Yup

#

That's it lol

tired lava
#

:)

past dagger
#

Huh

#

I suppose because it's a scriptable object

#

It does not reset values if adjusted during play mode (after closing play mode)

#

Interesting

tired lava
#

Yeah, it's often useful but sometimes annoying

past dagger
#

Yup

#

The benefit of having the one of these more global ones is that you've an overview of every sound though

#

Here you've to individually select each object

#

to adjust the settings

tired lava
#

True, but my project has over 600 AudioAssets. An unorganized list becomes a lot less useful when you have that many items.

past dagger
#

That's a lot of audio

tired lava
#

And that's only the audio clips I've made an audio asset for

past dagger
#

Wow

past dagger
#

But long term the overview would get jumbled

#

Due to the sheer amount of audio

tired lava
#

It would be possible to make a custom editor window that displays all the assets in a similar list, if you really wanted to

#

And you can make it more organized, based on folders for example

past dagger
#

Seems hard

#

Yeah figured that much

#

I wonder is there an easy way to group some together

past dagger
#

Since one is for charging and the other one is when it shoots

tired lava
#

I have AudioAssetCollections, but that's more for playing a random sound in a collection of slightly different sounds

past dagger
#

Right fair

tired lava
#

In the case of charging and shooting, you could make a ScriptableObject that has a "start sound" and an "end sound"

#

And maybe an optional looping middle sound

past dagger
#

complexity 100

#

I read on the internet a while ago that you cannot only have the first one have the header if you do it this way

#

So I imagine you don't know a way around other than, split them up too?

#

Like this

tired lava
#

Yeah, not much else you can do about that

past dagger
#

Yeah thought so

#

The next one you can keep going with , no problem though

#

Mainly just want it for this one specifically because it's a hot mess of serializedfields

#

Also FYI, not my code

#

Honestly kinda questionable how he made it but ig it works, so y'know ¯_(ツ)_/¯

#

Why does it say this

#

When it asks for 3 arguments

past dagger
#

I wanna mainly change the order bc I feel like my teammates won't be happy if new folder isn't on top lol

tired lava
past dagger
#

Yeah I'll look it up later

#

Anyway, thanks so much for all the help

#

Much appreciated!

past dagger
#

@tired lava Hey how would I go about pausing all audio?

#

Because I've been sitting here for a while and I cannot figure it out

#

Is that even a possibility with the current code that I've?

tired lava
past dagger
#

For now that’ll be fine thanks so much

#

Can’t believe I wasn’t able to find that

#

Probably just overly damn blind lmfao

past dagger
#

@tired lava Hey it's me again, uhm we're currently trying to add a settings menu that lowers the sound of all sounds, which we did by using a multiplier, like so:

    private static readonly int defaultValue = 1;
    private static readonly int multiplier = 1;

    [Range(0f, 1)]
    public float volume = defaultValue * multiplier;

But this would prevent us from being able to change sounds individually (most importantly the background music and the sounds)
So we thought we'd maybe add an enum option and loop through that to keep it seperate, but we're not quite certain how to do that

    public enum Type 
    { 
        Sound,
        Soundtrack
    }
    public Type type;
past dagger
#

@tired lava , pinged the wrong one first, woops

tired lava
past dagger
#

Could you please provide an example of that?

tired lava
#

You have to set up the AudioMixer and its groups in the editor and then reference them in code. The code would look something like this, in your script that receives the Sound scriptable object and sets up the AudioSource:

[SerializeField]
private AudioMixerGroup soundGroup;

[SerializeField]
private AudioMixerGroup soundtrackGroup;

private AudioMixerGroup GetAudioMixerGroup(Type type)
{
    return type switch
    {
        Type.Sound => soundGroup,
        Type.Soundtrack => soundtrackGroup
    };
}

...
// In your method where you are setting up the AudioSource:
audioSource.outputAudioMixerGroup = GetAudioMixerGroup(sound.type);
#

@past dagger

#

And then you change the volume of each group somewhere else, probably in your UI logic

#

You can find tutorials on that

past dagger
#

Thanks alot, I'll look into it :)

past dagger
#

Because I assume the AudioMixerGroup is the enum, it just doesn't match your example from before?

tired lava
#

No, AudioMixerGroup is a built-in Unity type representing the audio mixer group you have to create in the editor

past dagger
#

Oh

tired lava
#

The GetAudioMixerGroup method converts the Type enum (you should rename it) to its defined group

#

You could also reference the AudioMixerGroup directly in the Sound scriptable object, but I personally use my enum for more than just setting up the audio mixer

past dagger
# tired lava You could also reference the AudioMixerGroup directly in the Sound scriptable ob...

So I've tried stuff, but I'm a bit stuck on how to adjust the volume, since from what I understand I need

AudioManager.soundtrackGroup.audioMixer.SetFloat(param, param);

But then as string it wants an audioMixer which I do not really have, which I tried to add in on top but of course I never really assigned it anywhere so it'd always be null

public static AudioMixerGroup soundGroup, soundtrackGroup;
public static AudioMixer soundMixer, soundtrackMixer;

So currently rather stuck on this end, don't know what to do with the AudioMixer part of it

#

This'd about be the relevant code

AudioManager

    public static AudioMixerGroup soundGroup, soundtrackGroup;
    public static AudioMixer soundGroups, soundtrackGroups;

    private AudioMixerGroup GetAudioMixerGroup(AudioGroup audioGroup)
    {
        return audioGroup switch
        {
            AudioGroup.Sound => soundGroup,
            AudioGroup.Soundtrack => soundtrackGroup,
        };
    }

private void SetupSources(Sound sound)
    {
        if (sound.source == null)
            sound.source = gameObject.AddComponent<AudioSource>();

        sound.source.outputAudioMixerGroup = GetAudioMixerGroup(sound.audioGroup);

        sound.source.clip = sound.clip;
        sound.source.volume = sound.volume;
        sound.source.pitch = sound.pitch;
        sound.source.loop = sound.loop;
    }

Sound Class

using UnityEngine;

//Don't question why the order is 29 to be in the right place, I don't know either, I figured it out by trial and error.
[CreateAssetMenu(fileName = "New Sound", menuName = "New Sound", order = 29)]
public class Sound : ScriptableObject
{
    public enum AudioGroup
    {
        Sound,
        Soundtrack
    }
    public AudioGroup audioGroup;

    public AudioClip clip;

    private static readonly int defaultValue = 1;
    private static readonly int multiplier = 1;

    [Range(0f, 1)]
    public float volume = defaultValue * multiplier;

    [Range(0.1f, 3)]
    public float pitch = defaultValue;

    public bool loop;

    [HideInInspector]
    public AudioSource source;
}
tired lava
past dagger
#

Hm okay

#

So how'd I adjust the volume of a group then

tired lava
#

Do you want to do it from AudioManager?

past dagger
#

I think so?

tired lava
#

@past dagger Have you looked up a tutorial on how to use audio mixers for an audio settings menu?

past dagger
#

Unity Audio Mixers, adjustable with sliders and saving its values to persist! EVERYTHING YOU NEED TO KNOW comprehensive guide

How to add audio to your game (the basics of audio): https://youtu.be/eNi67i5my84

How to play a specific clip instead of a random one:

[SerializeField] AudioClip clip; //Just use a clip instead of a list

audioSource.P...

▶ Play video

Learn how to make an in-game options menu using Unity!

● Sign up for the Devdog Christmas Calender: http://bit.ly/DevdogGiveaway
● START MENU in Unity: https://youtu.be/zc8ac_qUXQY
● Ultimate Game UI: https://www.assetstore.unity3d.com/#!/content/53973?aid=1101lPGj

♥ Support Brackeys on Patreon: http://patreon.com/brackeys/

··················...

▶ Play video
#

The problem kinda lies with I don't see how I'd implement it with this system

#

Or I'm just dumb

#

Or really tired kek (or both)

#

Sorry if I'm a bother

tired lava
#

@past dagger I think you can follow the first tutorial. You don't have to do this from the AudioManager. It complicates things a bit because then you'll need your UI script that reads the values from the sliders to reference the AudioManager to do all the volume changing.

#

You definitely don't want your AudioManager to manage UI related things

past dagger
#

So where should my AudioMixerGroup variables be placed then? Not in the settings class right?

tired lava
#

The AudioManager needs to know which groups to assign to the AudioSources it spawns, so only the AudioManager needs references to the groups.

past dagger
#

So by that logic I should put the variables in the settings?

tired lava
#

Is the AudioManager the settings?

past dagger
#

No

tired lava
#

If the AudioManager needs references to the groups, it needs variables for the groups

past dagger
#

Yeah but should I put them within audiomanager like I've now

tired lava
#

The AudioManager looks fine to me now, except you don't need the two AudioMixer variables and they shouldn't be static

past dagger
#

Ah okay, thanks

tired lava
#

You need to make them assignable in the editor so you can select the mixer groups from the editor

#

Otherwise you need more complicated code to find the mixer groups from script

past dagger
#

Right okay

#

I was focusing purely on code so that's probably were it went wrong