- Home /
Audio Scripting
Hey everyone,
I have a whole load of sound files that I made for a game I'm working on and am wondering how to use the audio system built into unity because I it's my first time and I don't really understand the documentation. I managed to attach audio files and control them using scripts but the audio always gets cuts off when the projectile gets destroyed.
A solution that I think would work is to load all the audio into a script and use it as a manager for my audio files. So this way I think that I can load the sounds here and then use it from other scripts but what I don't know is how to set up the prefabs with audio sources so that I can individually tweek the values for different objects but at the same time play audio on top of one another without cutting anything off or even cutting off the audio when a projectile gets destroyed for example.
Do I need to dynamically create an object with the audio in it and have it move with the prefab projectile for example and let it play?
using UnityEngine;
using System.Collections;
//A Compressed version of the actual code
public class SoundManager : MonoBehaviour {
public GameObject soundClip;
public static AudioClip
//According to file in explorer
//Enemy [Movement]
EnemyAirSpawn, EnemyGroundSpawn, EnemyDeath, EnemyBaseMove, EnemyHeavyMove, EnemyCrusherMove, EnemyKamikazeMove, EnemyTurretMove,
//Enemy [Weapons]
EnemyBomb, EnemyMortar, EnemyMortarImpact, EnemyPlasma, EnemyPlasmaImpact, EnemyTesla,
void Awake()
{
string Path1 = "Sounds/Enemy/Movement/";
string Path2 = "Enemy/Weapons/";
//Path 1 sounds
EnemyAirSpawn = (AudioClip)Resources.Load(Path1 + "EnemyAirSpawn");
EnemyGroundSpawn = (AudioClip)Resources.Load(Path1 + "EnemyGroundSpawn");
//Path 2 sounds
EnemyBomb = (AudioClip)Resources.Load(Path2 + "EnemyBomb");
EnemyMortar = (AudioClip)Resources.Load(Path2 + "EnemyMortar");
EnemyMortarImpact = (AudioClip)Resources.Load(Path2 + "EnemyMortarImpact");
EnemyPlasma = (AudioClip)Resources.Load(Path2 + "EnemyPlasma.ogg");
EnemyPlasmaImpact = (AudioClip)Resources.Load(Path2 + "EnemyPlasmaImpact.ogg");
EnemyTesla = (AudioClip)Resources.Load(Path2 + "EnemyTesla");
}
}
In addition to my answer below, a friendly advice: It will be much easier for people to help you if a) your question is short and clear and b) your code is properly formatted and contains only the $$anonymous$$imal bits needed for people to understand / reproduce the problem.
Thank you and yeah haha I was unsure about how to input code but I fixed the code placement and I'll try to cut it down. Thanks! =D
Dude... shorten the code! :)
This almost looks like a full game... heh.
Answer by DannyB · Aug 17, 2012 at 07:09 AM
To avoid sound cutoff, do not destroy the object until it has finished playing the sound. Instead, hide it on impact and destroy it after a few seconds.
audio.Play();
gameObject.renderer.enabled = false;
Destroy( gameObject,2 );
Hey thanks for the reply! Yeah I was thinking about that too but I'm going to port this onto a mobile game with many projectiles at once, do you think this is the best way?
I think it is a good way, and maintenance wise, it is probably the preferred way.
Of course, there is always the option of a "manager", but consider the implications, mainly:
You will have to place it where the actual sound happens, or at least "in the neighborhood" for 3D sound positioning.
You have another foreign object to handle, you will need communication to and from other objects.
You will not be utilizing the intended (or at least natural) Unity design, being: object has an audio source that can be played at will, Unity takes care of the rest.
Lastly, if for some reason the "lazy destroy" method does not work for you and you are sure it cannot be corrected, I would still try to avoid a manager, and ins$$anonymous$$d, just spawn an empty object in the place of impact, which does a simple thing: Play audio on instantiation, and "commit suicide" after X seconds, so at least you will have a lightweight object there.
If you want to avoid having too much of these, you can use some object recycling method that makes sure there are only X number of "audio objects" on the screen, but I think this is way down the road, if all else fails.
Thanks for your answer once again. I think you're right and I will now proceed to try it out.
However I'm wondering because I'm confused but is this the way to do it?
Declare AudioClip.
Assign it in the inspector
Include an AudioSource component in the prefab
(This is the part I'm confused about) Do I use audio.Play(), audio.PlayOneShot(Clip) or do I use AudioSource.PlayClipAtPoint(myClip, transform.position). Because my intention is to have layered sounds with many many objects at the same time (I'll mix it later) which one do I use?
Well, this is what I do:
Add an Audio Component to my prefab object.
Select a sound file as the Audio Clip, and disable the Play on Awake checkbox.
Then, in the script that is attached to the object I do audio.Play()
If I want the object to play one of several possible sounds, I either declare an AudioClip Array in the script, or declare several AudioClip variables, ( e.g. public AudioClip[] explosions; ) and then before audio.Play() I use audio.clip = explosions[2] or something similar.
You may use PlayOneShot() when you have an AudioClip variable to pass.
Thanks! well I'm trying out pretty much in theory what you suggested and it's going O$$anonymous$$ so far but I'll report back when I'm complete.
Your answer
Follow this Question
Related Questions
How To Turn Off Sound For Certain Objects? 1 Answer
Audio Play Once 2 Answers
Trigger audio loop on beat with PlayScheduled 1 Answer
How do I fix audio loop delay 2 Answers
Mute volume / sound problem 1 Answer