- Home /
Play Audio on Key Press when within trigger or use raycast??
So basically I want to be able to walk up to objects in my game and if I am within the trigger of said object and press the E key it will play an audio clip. Id want to do this with many of my objects in the game. EXAMPLE: Call of Cthulhu Dark Corners of the Earth, in this game you can walk up to objects, hit the E key and many times he will say something audible such as, " Its a bookcase nothing special"
Anyone have an idea of a good way to do this, I am new to writing scripts and what not but any help would be greatly appreciated.
The best answer thus far was this solution:
The whole thing should be like this:
Player script: var range: float = 5; // define the detection distance private var hit: RaycastHit;
function Update(){ if (Input.GetKeyDown("e")){ var ray = Camera.main.ViewportPointToRay(Vector3(0.5,0.5,0)); if (Physics.Raycast(ray, hit, range)){ // check if the object hit has SoundScript.js: var ss: SoundScript = hit.transform.GetComponent(SoundScript); if (ss){ // if so, play its sound: audio.PlayOneShot(ss.soundFX); } } } } Object script (save it as SoundScript.js!): var soundFX: AudioClip; // select the sound for each object Just attach the SoundScript to every "talking object" and define its Sound FX field in the Inspector. This alternative saves resources and only detects things that are in front of the player, but has fixed detection range.
Answer by aldonaletto · Aug 26, 2012 at 10:33 AM
@Piflik 2nd alternative is good, uses less resources and directly solves the audio rolloff problem, but if you prefer triggers (they're easier to handle in the Editor), do the following:
1- create a trigger volume (a box or sphere collider);
2- add an AudioSource to it, and set the AudioSource Pan field to 0 in order to have a constant sound even if the player walks away;
3- add the script below to the trigger;
4- drag the trigger to the Project window to make it a prefab.
private var inTrigger = false; // becomes true when the player is inside
function OnTriggerEnter(other: Collider){ // check if it's the player (remember to tag it "Player"): if (other.tag == "Player") inTrigger = true; }
function OnTriggerExit(other: Collider){ if (other.tag == "Player") inTrigger = false; }
function Update(){ if (inTrigger && Input.GetKeyDown("e") && !audio.isPlaying){ audio.Play(); } } When you want to add voice to some object, just drag the trigger prefab to it, then adjust the trigger's rotation/position/dimensions and drag the desired sound to its AudioSource Clip field.
That is the best answer for what im trying to do so far, it looks like you get exactly what im trying to do and yes the ease of using those triggers in the editor. Now I attached that JavaScript to my trigger, made sure my player object was tagged as Player and walked into it and pressed E and nothing happens. I also get a yellow message on the bottom that says,The referenced script on this Behaviour is missing! Any idea what im doing wrong?
Add some debugging instructions to help understanding what's going wrong - like this:
function OnTriggerEnter(other: Collider){ if (other.tag == "Player"){ inTrigger = true; print("Player in"); } }
function OnTriggerExit(other: Collider){ if (other.tag == "Player"){ inTrigger = false; print("Player out"); } }
function Update(){ if (inTrigger && Input.Get$$anonymous$$eyDown("e") && !audio.isPlaying){ print("Play message"); audio.Play(); } } The missing behaviour message doesn't seem related to this problem - it usually appears when you delete a script that was attached to some object.
Answer by Piflik · Aug 25, 2012 at 10:18 PM
There are many possibilities to do that. One would be a raycast that makes the object that is being hit play its sound.
Example:
Script for the Player:
Function Update() {
var fwd = transform.TransformDirection (Vector3.forward);
if(Input.GetKeyDown("f")) {
if (Physics.Raycast (transform.position, fwd, hit, 10)) {
hit.gameObject.SendMessage("PlaySound");
}
}
}
Script for the object:
var soundFX : AudioClip;
Function PlaySound() {
audio.Play(soundFX);
}
Haven't tested these, so I'm not sure they do what I think they do, or even work ;)
When I think about it, it might be better to make the player play the audio file, ins$$anonymous$$d of Send$$anonymous$$essage...the latter is a bit slow...should not matter in this case, but anyways:
Player:
Function Update() {
var fwd = transform.TransformDirection (Vector3.forward);
if(Input.Get$$anonymous$$eyDown("f")) {
if (Physics.Raycast (transform.position, fwd, hit, 10)) {
audio.Play(hit.GetComponent(ObjectScript).soundFX);
}
}
}
Object:
var soundFX : AudioClip;
Replace'ObjectScript' with whatever you call your Object's script.
Thanks for the replies! I tried both of these suggestions and im getting all kinds of debugging errors. Is there just a way where I can make it so A. Character in game walks up to an object. B. Said object has an invisible trigger C. When Character is WITHIN the trigger and the character hits the E key it plays an audio clip on the character and then if that character walks away it will still keep playing till the clip is done, if the character walks back into the trigger and hits the E key it will play it again. I want it so if the audio clip is playing and the character walks away from the object that audio does not start to fade or sound distant but constant same volume. Then lets say the character walks across the room to another object, enters that objects invisible trigger and hits the E key, it plays a different sound that is specific to that object. EXA$$anonymous$$PLE, Character walks up to a picture frame and hits the E key, audio plays " Its a picture of some old man." character walks away (out of the trigger) before the audio is done playing but the audio plays until its finished. Character walks to the other side of the room to a fireplace and when they are close enough A$$anonymous$$A INSIDE the trigger for the fireplace and the character hits the E key it does the same thing and plays a audio clip such as " this fireplace smells of burnt meat". That is what I am trying to accomplish. Thanks for any help. For a further example, play Call of Cthulhu Dark Corners of the Earth. Again thanks for ANY help.
The second @Piflik alternative is just a suggestion - you should complete it. The whole thing should be like this:
Player script:
var range: float = 5; // define the detection distance private var hit: RaycastHit;
function Update(){ if (Input.Get$$anonymous$$eyDown("e")){ var ray = Camera.main.ViewportPointToRay(Vector3(0.5,0.5,0)); if (Physics.Raycast(ray, hit, range)){ // check if the object hit has SoundScript.js: var ss: SoundScript = hit.transform.GetComponent(SoundScript); if (ss){ // if so, play its sound: audio.PlayOneShot(ss.soundFX); } } } }
Object script (save it as SoundScript.js!):
var soundFX: AudioClip; // select the sound for each objectJust attach the SoundScript to every "talking object" and define its Sound FX field in the Inspector. This alternative saves resources and only detects things that are in front of the player, but has fixed detection range.
Ok im dumb, it IS working. I had hit the mute key on my keyboard. SO this is the kinks i need to work out now, it still keep saying that the referenced script on this behaviour is missing, when i doubleclick on that error message it keeps on opening the player script. One other thing, when i hit e and am within distance and looking at the object it plays the audio, if i hit e again while the audio is playing it will start playing the audio AGAIN over the top of the audio that is already playing, so basically if i keep hitting the e key looking at the object it will keep playing the audio over and over till its echoing many times over itself. Any way to control that? maybe some sort of timer i can adjust for different length audio files so if i hit e on an object a timer starts and if i hit e again before that timer finishes it will not play the audio again. And when the timer finishes if i hit e at that point it will play the audio again? I dont know any thoughts?
That's a PlayOneShot characteristic. You can use Play ins$$anonymous$$d, with a few changes:
... if (ss){ // if so, play its sound: audio.clip = ss.soundFX; audio.Play(); }This will stop and restart the sound each time you press $$anonymous$$ If you want to ignore E while the sound is playing, change to this:
... if (ss && !audio.isPlaying){ // if so, play its sound: audio.clip = ss.soundFX; audio.Play(); }
Your answer
Follow this Question
Related Questions
Play Audio Sound OnTriggerEnter 2 Answers
Audio fade after entering trigger? 0 Answers
Play random sound on NPC when trigger enter 1 Answer
GetComponent().Play(); Question(s) 2 Answers