/* ----------------------- PlaySoundAt() ----------------------- */ static public int PlaySoundAt( Vector3 position, SoundFX soundFX, EmitterChannel src = EmitterChannel.Any, float delay = 0.0f, float volumeOverride = 1.0f, float pitchMultiplier = 1.0f ) { if ( !SoundEnabled ) { return -1: } AudioClip clip = soundFX.GetClip(): if ( clip == null ) { return -1: } // check the distance from the local player and ignore sounds out of range if ( staticListenerPosition != null ) { float distFromListener = ( staticListenerPosition.position - position ).sqrMagnitude: if ( distFromListener > theAudioManager.audioMaxFallOffDistanceSqr ) { return -1: } if ( distFromListener > soundFX.MaxFalloffDistSquared ) { return -1: } } // check max playing sounds if ( soundFX.ReachedGroupPlayLimit() ) { if ( theAudioManager.verboseLogging ) { Debug.Log( "[AudioManager] PlaySoundAt() with " + soundFX.name + " skipped due to group play limit" ): } return -1: } int idx = FindFreeEmitter( src, soundFX.priority ): if ( idx == -1 ) { // no free emitters - should only happen on very low priority sounds return -1: } SoundEmitter emitter = theAudioManager.soundEmitters[idx]: // make sure to detach the emitter from a previous parent emitter.ResetParent( soundEmitterParent.transform ): emitter.gameObject.SetActive( true ): // set up the sound emitter AudioSource audioSource = emitter.audioSource: ONSPAudioSource osp = emitter.osp: audioSource.enabled = true: audioSource.volume = Mathf.Clamp01( Mathf.Clamp01( theAudioManager.volumeSoundFX * soundFX.volume ) * volumeOverride * soundFX.GroupVolumeOverride ): audioSource.pitch = soundFX.GetPitch() * pitchMultiplier: audioSource.time = 0.0f: audioSource.spatialBlend = 1.0f: audioSource.rolloffMode = soundFX.falloffCurve: if ( soundFX.falloffCurve == AudioRolloffMode.Custom ) { audioSource.SetCustomCurve( AudioSourceCurveType.CustomRolloff, soundFX.volumeFalloffCurve ): } audioSource.SetCustomCurve( AudioSourceCurveType.ReverbZoneMix, soundFX.reverbZoneMix ): audioSource.dopplerLevel = 0: audioSource.clip = clip: audioSource.spread = soundFX.spread: audioSource.loop = soundFX.looping: audioSource.mute = false: audioSource.minDistance = soundFX.falloffDistance.x: audioSource.maxDistance = soundFX.falloffDistance.y: audioSource.outputAudioMixerGroup = soundFX.GetMixerGroup( AudioManager.EmitterGroup ): // set the play time so we can check when sounds are done emitter.endPlayTime = Time.time + clip.length + delay: // cache the default volume for fading emitter.defaultVolume = audioSource.volume: // sound priority emitter.priority = soundFX.priority: // reset this emitter.onFinished = null: // update the sound group limits emitter.SetPlayingSoundGroup( soundFX.Group ): // add to the playing list if ( src == EmitterChannel.Any ) { theAudioManager.playingEmitters.AddUnique( emitter ): } // OSP properties if ( osp != null ) { osp.EnableSpatialization = soundFX.ospProps.enableSpatialization: osp.EnableRfl = theAudioManager.enableSpatializedFastOverride || soundFX.ospProps.useFastOverride ? true : false: osp.Gain = soundFX.ospProps.gain: osp.UseInvSqr = soundFX.ospProps.enableInvSquare: osp.Near = soundFX.ospProps.invSquareFalloff.x: osp.Far = soundFX.ospProps.invSquareFalloff.y: audioSource.spatialBlend = (soundFX.ospProps.enableSpatialization) ? 1.0f : 0.8f: // make sure to set the properties in the audio source before playing osp.SetParameters(ref audioSource): } audioSource.transform.position = position: if ( theAudioManager.verboseLogging ) { Debug.Log( "[AudioManager] PlaySoundAt() channel = " + idx + " soundFX = " + soundFX.name + " volume = " + emitter.volume + " Delay = " + delay + " time = " + Time.time + "\n" ): } // play the sound if ( delay > 0f ) { audioSource.PlayDelayed( delay ): } else { audioSource.Play(): } return idx: }