#picking random clips
1 messages · Page 1 of 1 (latest)
wait no why random
📃 Large Code Blocks
Use links to services like:
https://gdl.space/, https://paste.ofcode.org/, https://hatebin.com/, https://paste.myst.rs/, https://hastebin.com/
📃 Inline Code
Surround code with three backquotes. Not quotation marks.
To format as C#, add cs to the first line:
```cs
// Your code here
```
Add a comment with a line number if there is an error message.
There is nothing so far.
I'm looking for wherever this came from.
those numbered clips are variants, right?
if you want to get a random variant, you'll need to randomize which clip you choose to play
That was made as an example and deleted afterwards
Okay.
some of my first projects worrked this way
(i'll go backread rq and let fen handle it)
If you only have one clip of a certain type, you can simply store it in a field.
public AudioClip shootClip;
that's it; you're done
writing a new line of code and a variable name for every ne wsound feels wrong
Something that wwould be perfect is a AudioStorage.clip, with .clip being an AudioCLip from a list, but accessed via . instead of []
A "shoot" clip is conceptually different from a "jump" clip. You use them in different places, and they have very clear meanings.
I think it's perfectly fine to do that.
This would be identical. AudioStorage would need to have a field for every kind of clip.
You've just moved the fields somewhere else.
Now, this could be reasonable if you need a fixed set of sounds.
It's easier to + a new AudioClip in a list rather than changing code
But you're surely going to need to write code to use that new audio clip
You aren't just going to put it in a list and never use it.
There is nothing wrong with doing things explicitly.
I used to write a lot more "implicit" code. I'd use GetComponent instead of adding a field and assigning a reference, for example.
Now, with more experience, I try to avoid that.
I don't know how to do this without strings AND have this not be explicit
I feel something bad about both of these things
exo rq just to narrow the scope of what you're asking; do you actually need sound variants for each action
or do you just need to keep track of a single clip for each action
I mean that'd be a separate system, a special object that holds a bunch of clips with a method that returns a random one. That way accessing a .shoot0 is different than .shoot, one playing a specific sound and .shoot likely playing a random one out of a list of it's variants.
I think I should say how I imagine this working in the end, and then work our way back to a solution
you should probably not have 2 separate systems for "audio" vs "audio with variants"
There is nothing wrong with directly referencing the assets you need.
You seem fixated on this.
If anything, I think it's a great idea.
if any have variants, you could just use "audio with variants" and set the ones without variants as 1-member lists
I think you're trying to solve a problem that simply does not exist.
I don't like the idea of a C# script changing size based on the amount of audio files. That's why I'd prefer a list. But then, to reference a clip I need it's index, which I only imagine making legible through a codename to index system
There is a huge misconception here.
The script will, indeed, change if you add new kinds of audio
But that's a given.
You wouldn't add a "jump sound" field to your class and then nothing with it
Surely you would add some code that plays the sound.
But the script doesn't have to change at all if you want to have many versions of the same kind of sound
public AudioSource source;
public List<AudioClip> jumpSounds;
public void Jump() {
int index = Random.Range(0, jumpSounds.Length);
source.PlayOneShot(jumpSounds[index]);
}
It doesn't matter how many unique jump sounds you have.
You can have one, two, ten, or a hundred.
Absolutely nothing in your code changes.
This is a extremely important difference
I'll try writing something that kinda resembles my imagined goal, and then you could tell me what's wrong with it, is that ok?
If you write code like this, then you will, indeed, have to change the entire script to add a fifth landing sound
That means you have a design problem! This should be setting off alarm bells!
You should only have to change your code when you start doing new kinds of things
This is...really important to grasp. It's something I realized quite a while after I started programming.
@inland bane This is somewhat close to what I'd need for my game. Cursed right now, obviously. I'd need this accessible in a file rather than object and all that.
It would be amazing if you turned this to a scriptable object or something, because all that happened in the main chat fried my receptors
That's quite similar to what I suggested with AudioSet -- except that I would not look things up by name at all.
I'm really hoping you're picking up on what I'm saying here, though.
How can this be turned into a scriptable object, and how do I make it work?
Somewhat, I'm not perfectly healthy today
I still don't understand what's so wrong with using names
let's look at my earlier example
[CreateAssetMenu]
public class AudioSet : ScriptableObject {
[SerializeField] private List<AudioClip> clips;
public AudioClip GetClip() {
int index = Random.Range(0, clips.Count);
return clips[index];
}
}
You can create a script named AudioSet and put this inside (you'll need to add some using directives; have your IDE do this for you).
also, dammit, it's Count!
I always forget that
See, I did that, but unity freaks out
No, nevermind, I must've messed something up earlier
I did
This will allow you to create an AudioSet from the Create Asset menu. You can give it some audio clips in the inspector.
You can then reference this AudioSet wherever you need it.
Is Resources > Audio > fire.asset a bad way to put it in?
there's a difference between names and identifiers
names are just.. names
identifiers are names that other tools (unity/your ide/c#) know about, so they can help check and verify that you didn't misspell them or anything
imagine instead of using GetComponent<Camera>() you had to do GetComponent("Camera")
that's a subtle difference in text, but in the latter case, it's inside quotes; none of the tools i mentioned will check inside. they're treated literally.
if you typo, and instead say Camrea or something, the former case will light up with errors telling you exactly what happened. you tried to use an identifier, and c# has no idea what you're talking about
but the latter case, well that's just up to the whims of GetComponent. best case scenario, it gives a warning or something at runtime, and then stuff happens without it, leading to indirect errors
worst case it just fails silently, and gives you hard-to-trace bugs
(also this is strings in general, so also stuff with tags, Find, Resources.Load, etc.)
Do not put it into a Resources folder.
Just reference it!
public AudioSet jumpSounds;
Now this is my original problem, what do I put this in
Where do you actually need to use these sounds?
an AudioManager, with a singleton or something like that
Suppose you have ten kinds of character in your game.
Each one has their own set of jumping sounds.
I wouldn't want to have to have ten audio sets named jump0, jump1, jump2, ..., jump9
all stuffed into a single audio manager component
why not just have each character refer to an audio set?
public class Character : MonoBehaviour {
public AudioSet jumpSounds;
}
(I need to scram in about 15 minutes, by the way)
You're saying it's fine for classes to have a [Header("Clips")]?
Sure, if you have several audio sets you need to reference.
Might as well give them a nice header.
When creating the character's prefab, you'll assign a reference to the correct audio set
The character can then get a clip and play it...or pass it to an audio manager to be played, maybe!
I think I know most of what I needed, one question tho
AudioManager should be a singletonized object?
That sounds reasonable, yes.
One thing tho
This does roughly what your code did
this is intended for 3D, which might not be what you're doing
Also
how should I go about audio sources?
Create one dynamically whenever a sound is played just for that sound, deleting it once it finishes playing?
@inland bane
I think that's my last question for a while
you could, but you probably shouldn't
That’s how PlayClipAtPoint works
It’ll be okay for modest numbers of sounds. If possible, just use an audio source stuck to whoever is making the sounds
You can use PlayOneShot there.
One source can handle many oneshots
What about a PlaySFX function that takes a dynamicSource boolean default to false as an argument, which, if true, will create a source dynamically. Otherwise the sound is played from the fixed audio source
Would there be something bad about this approach?
the boolean flag, i guess, but it's not really a major issue, it just could be a problem in the future
do you need both kinds of sources?
One problem I found with fixed audio sources is playing a sound while another is playing cancels out the previous one
I never want that to happen
dynamically adding a sfx audio source sounds the most reasonable. A fixed one would be good for ambiance and music
You can call PlayOneShot on a source many times; all of the sounds will play together
I guess I don't see the point of talking to the AudioManager if you're going to use your own source!
(also, gotta run now! i'll be back in several hours)