I’ve run into a problem that appeared to be more of a mouthful than I thought. Trouble is, I have an amount of rigidbodies with attached audiosources, that the player is able to move around from one zone to the other.
I need a fail-proof solution, that plays the audiosources currently placed inside a trigger to start playing when the player enters the trigger, and stop when the player exits.
Since the audiosources are to be moved from one trigger to another, I cant just put the audiosources into a locked script that just plays a preselected amount of audiosources, but needs to be able to dynamically play only the audiosources currently inside the trigger zone.
I’m using C#, and I’m not quite sure on how to do this.
My current idea is next-to nonexistant, since my first plan went down the drain and failed completely.
Anyone able to point me in a direction for a good solution to my problem? Or have some bits of scripts to give me an idea of how to set this up?
public class AudioHolder : MonoBehavior {
public AudioClip playClip;
}
Explanation
Everytime your audio source (which is moving, either by itself, or affected by its parent) enters a trigger zone [OnTriggerEnter()]
it will look for the AudioHolder component [GetComponent()]
If the trigger zone have that component (therefore, it is your trigger zone with sound, example, environment sound) [ if( ah != null ) ]
The AudioPlayer will sets its clip to be the trigger zone’s clip and play it. [ audio.clip = ah.playClip; audio.Play(); ]
I am throwing-in a triggerCount for the case of overlapping trigger zones(You can figure this one out yourself, just experiment with different trigger zone setup and comment-out some of the codes)
P/s: Code is not checked for syntax errors or actually tested.
Add a script to the trigger that adds any object of interest to a local list, and play/stop their sounds when the player enters/leaves the trigger - and also remove from the list the objects that exit the trigger. You should use some specific tag to identify the rigidbody+audiosource objects - “SoundSource”, for instance:
using UnityEngine;
using System.Collections.Generic;
public class RegisterAudioSources: MonoBehaviour {
private List<AudioSource> soundList = new List<AudioSource>();
void OnTriggerEnter(Collider other){
if (other.tag == "SoundSource"){ // sound object entering the trigger?
soundList.Add(other.audio); // add it to the list
}
else
if (other.tag == "Player"){ // player entering trigger?
foreach(AudioSource sound in soundList){ // play all sounds in the list
sound.Play();
}
}
}
void OnTriggerExit(Collider other){
if (other.tag == "SoundSource"){ // sound object leaving the trigger?
soundList.Remove(other.audio); // yes: remove it from the list
}
else
if (other.tag == "Player"){ // player leaving the trigger?
foreach(AudioSource sound in soundList){
sound.Stop(); // yes: stop all sounds in the list
}
}
}
}
This should work, unless the way the sound objects are moved by the user into the triggers doesn’t generate OnTrigger events.