Scripting An Object to play a sound effect on collision

Hey everyone, I don’t have a large knowledge of scripting at all but I am try to learn JavaScript for unity.I’m trying to set up an object to play a sound effect whenever an object(my player for now)collides with another object.I don’t have much to go off of here so I’m pretty much starting off from scratch. I did get some help earlier helping me with where to put the code for the sound which he learned from the Manual Reference. Here’s what I got so far:

var pickupSound : AudioClip;
var audioPos : Vector3;

function Update();
{


	//When There is Contact between player and object this is known as OnTriggerEnter//
	function OnTriggerEnter () {
	AudioSource.PlayClipAtPoint(pickupSound, audioPos);
	//Destroy the game object//
    Destroy(gameObject);
	} 


/*Make sure to have this script on the object that you want to destroy
Also make sure that you have IsKinematic unchecked
OnTriggerEnter is used when you want to destroy or "Trigger" an object
On Collision Enter is for when you want to collide with an object
*/


}

if anybody could help me add on and fix this up a litle bit it would be very much appreciated.

Close, but you can’t nest functions inside other functions like that. In this case you have something you want to have happen only when the trigger fires, so keep OnTriggerEnter and remove the enclosing Update:

var pickupSound : AudioClip;
var audioPos : Vector3;

//When There is Contact between player and object this is known as OnTriggerEnter//
function OnTriggerEnter () {
   AudioSource.PlayClipAtPoint(pickupSound, audioPos);
   //Destroy the game object//
    Destroy(gameObject);
}

Awesome,Works just how I wanted it to.I just have 1 more question when i pick up the object it will play the sound but say i pick up another right after it the sounds both play at the same time and finish through.I did hear something about putting each sound clip on different channels(or something like that) so that you could avoid problems like this.Any suggestions?

The method shown (using PlayClipAtPoint()) will effectively assign the sounds to different channels, I believe. Is that not the behavior that you want? Can you explain in detail what you want to have happen (sound-wise) when multiple items are picked up in quick succession?

Thank you for your reply you did make me think for a second what DO i want to do.I thought for a second and figured it out.I want it to play the sound of the 1st item pickup and if i pickup more it should override the 1st pickup sound.If you get what I mean.Basically it should only ever play 1 audio clip instead of them all playing at once.Here’s my script of what I have set up:

var pickupSound : AudioClip;
var audioPos : Vector3;

	//When There is Contact between player and object this is known as OnTriggerEnter//
	function OnTriggerEnter () {
	AudioSource.PlayClipAtPoint(pickupSound, audioPos);
	//Destroy the game object//
    Destroy(gameObject);
	} 


/*Make sure to have this script on the object that you want to destroy
Also make sure that you have IsKinematic unchecked
OnTriggerEnter is used when you want to destroy or "Trigger" an object
On Collision Enter is for when you want to collide with an object
*/




/*Close, but you can't nest functions inside other functions like that. In this case you have something you want to have happen only when the trigger fires, so keep OnTriggerEnter and remove the enclosing Update:
Code:

var pickupSound : AudioClip;
var audioPos : Vector3;

//When There is Contact between player and object this is known as OnTriggerEnter//
function OnTriggerEnter () {
   AudioSource.PlayClipAtPoint(pickupSound, audioPos);
   //Destroy the game object//
    Destroy(gameObject);
} 
*/

Sorry to reference other games but sort of like how when you pick up money in GTA San Andreas.Im kinda looking for something of that effect. :slight_smile:

So each time the player gets a pickup it should stop and currently playing clip and start playing it again from the beginning? Or do you mean you want to skip starting a new clip if there’s one playing already?

The latter is easy enough; just store the time you start the clip playing:

lastPlayed = Time.time

and then don’t start another clip if the last one hasn’t finished yet:

if (lastPlayed + clipLength > Time.time) return;

If you want to stop and restart the audio clip, you’ll need to add a bit more code, as show here. You’d call PlayAudoSource() from OnTriggerEnter() to play your clip, and store the AudioSource instance it returns. Before calling it, you’d use that saved reference to cancel any previously started clip. Something like (will need some cleaning up probably):

static pickupSource : AudioSource;
var pickupSound : AudioClip;
var audioPos : Vector3; 

function OnTriggerEnter() {
  if (pickupSource != null) pickupSource.Stop();
  pickupSource = PlayAudioClip(pickupSound, audioPos, .5f);
  Destroy(gameObject);
}

function PlayAudioSource(...) { ... }

I don’t code in UnityScript anymore, so I forget if that’s the right way to declare a static variable; it needs to be static so all your pickups share a common reference to it.

Again thank you for the response.So I’m gonna go ahead and use the 1st option :

lastPlayed = Time.time

if (lastPlayed + clipLength > Time.time) return;

I read your directions but again i know nothing about scripting and dont fully understand on what you are saying about storing the time and all that.If you could direct me a little bit it would be very helpful.

Storing the time is what you’re doing there with ‘lastPlayed = Time.time’. If that approach gives you a solution you’re happy with, no need to worry about the second option :slight_smile:

So what your saying (if I see understand correctly)that Time.time is going to be a decimal since its a floating point.But I dont have an my audio set to a time its just my script set up to it.And the soundclip is exposed to the Inspector.

Time.time had a float (decimal) value, yes. The rest of your post, though, I didn’t follow :frowning:

I appoligize for the poor post earilier and the following one.Im not 100% sure about all of the terms that I am about to use so please bear with me.My question again is getting the sound clip to play when i destroy an object.The problem is that if i pickup(destroy)multiple objects 1 right after another it will play each sound and they will run all at the same time.You posted 2 possible solutions a simple fix and a 2nd option.I decided to use thr 1st heres the script that you provided.

lastPlayed = Time.time

if (lastPlayed + clipLength > Time.time) return;

I then asked if you could explain to me what to fill in thats just a place holder for now because I have no prior knowledge of scripting.This is my script that i have now and I dont know where to put the 2 lines of code that you posted for me.Also i am now sure of what to put in the code for myself.If you could provide a little more explanation on what to fill in It would be ver helpful.Sorry for the trouble.

var pickupSoundLength : float;
var pickupSound : AudioClip;
var audioPos : Vector3;

// every instance of this script on every object
// it is attached to needs to be able to find out
// the last time s pickup sound was played. by 
// making this var static, it is shared across all
// instances ('copies of') this script.
private static var lastPlayed : float = 0;

function OnTriggerEnter () {
   // if lastPlayed is 0 we haven't played any
   // pickup sounds yet; if it isn't 0, we need
   // to check if the last sound is still playing
   if (lastPlayed != 0) {
      // lastPlayed + pickupSoundLength is the time
      // at which the last audio clip finishes. if
      // that is after the current time, the clip
      // is still playing
      if (Time.time < lastPlayed + pickupSoundLength) {
         // last clip is still playing. we don't want
         // to play it again. Just destroy the game
         // object and finish
         Destroy(gameObject);
         return;
      }
   }

   // if we get to this point we either haven't played
   // and sounds yet, or the last one we played has
   // finished. we want to start a new audio clip,
   // and remember what time it started so the code
   // above can check whether or not it's finished
   // next time through.
   lastPlayed = Time.time; // remember start time
   AudioSource.PlayClipAtPoint(pickupSound, audioPos);

   //Destroy the game object//
   Destroy(gameObject);
}

ETA: I didn’t test it; same caveat as before about syntax for declaring static vars in UnityScript (if that gives a syntax error, check the scripting docs)

Success! Thank-you very much for the help I really appreciate it.Also Thank-you for putting in comments along with it.