Play audio-sources in trigger zone when player enters

Good morning/evening everyone!


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?

Thanks in advance :slight_smile:

Assumption: You can setup the trigger.

Script

Audio Player: Attach this one to your audio source

public class AudioPlayer : Monobehaviour {
   
   private int triggerCount = 0;

   void OnTriggerEnter( Collider collider ) {
      AudioHolder ah = collider.gameObject.GetComponent<AudioHolder>();

      if( ah != null ) {
         audio.clip = ah.playClip;
         audio.Play();
         triggerCount++;
      }
   }

   void OnTriggerExit( Collider collider ) {
     AudioHolder ah = collider.gameObject.GetComponent<AudioHolder>();

      if( ah != null ) {
         triggerCount--;
         if( triggerCount <= 0 ) {
            audio.Stop();
         }
      }
   }
}

AudioHolder: Attach this one to the triggers

public class AudioHolder : MonoBehavior {
   public AudioClip playClip;
}

Explanation

  1. Everytime your audio source (which is moving, either by itself, or affected by its parent) enters a trigger zone [OnTriggerEnter()]
  2. it will look for the AudioHolder component [GetComponent()]
  3. If the trigger zone have that component (therefore, it is your trigger zone with sound, example, environment sound) [ if( ah != null ) ]
  4. 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.