Hello everyone,
Using Unity 2022.2.18
Currently implementing Csound in a 3D environment with many sound sources and various cabbage instruments. The CsoundUnity components and their respective AudioSource are contained in the spawned map object/npc prefabs.
In hopes of optimising performance, I’m testing a script called AudioCullingManager that manages all of the map objects in the game world, getting all of their relevant audio components and enabling/disabling them when crossing a distance threshold relative to the player.
AudioCullingManager script:
using UnityEngine;
using System.Collections.Generic;
public class AudioCullingManager : MonoBehaviour
{
public Player player;
public float cullingDistance = 50f; // Distance threshold for audio culling
[SerializeField] private List<GameObject> audioEmitterObjs = new List<GameObject>(); // Pool of objects with audio components
public MapObjGen mapObjGen;
private void Awake()
{
mapObjGen = GetComponentInParent<MapObjGen>();
}
public void InitAudioCulling()
{
foreach (GameObject mapObj in mapObjGen.mapObjectList)
{
if (mapObj.GetComponentInChildren<AudioSource>() != null || mapObj.GetComponentInChildren<CsoundUnity>() != null)
{
audioEmitterObjs.Add(mapObj);
}
}
}
void Update()
{
if (player != null)
{
foreach (GameObject audioEmitterObj in audioEmitterObjs)
{
float distance = Vector3.Distance(audioEmitterObj.transform.position, player.transform.position);
// Get components on each audioEmitterObj
var audioSources = audioEmitterObj.GetComponentsInChildren<AudioSource>(true);
var csoundUnityComponents = audioEmitterObj.GetComponentsInChildren<CsoundUnity>(true);
bool shouldEnable = distance <= cullingDistance;
// Enable/disable CsoundUnity components
foreach (var csoundUnity in csoundUnityComponents)
{
csoundUnity.enabled = shouldEnable;
}
// Enable/disable AudioSource components
foreach (var audioSource in audioSources)
{
audioSource.enabled = shouldEnable;
}
}
}
}
This script does indeed do what is described, but I fear that due to disabling/enabling them, the sound is lost. Is it possible to dynamically turn these components on and off? Or would I need to reinitialise them somehow?
I also make sure that i’m checking the cSoundUnity component is not null when making any parameter changes (that are called even if the sound is off, currently). Heres an example:
CabbageAudioManager script (Manages Cabbage instrument parameters)
public void SetParameter(CsoundUnity cSound, string parameterName, float value)
{
if (cSound != null && cSound.GetChannel(parameterName) != value)
{
cSound.SetChannel(parameterName, value);
}
//Debug.Log($"Parameter {parameterName} set to: {value}");
}
I am aware Unity has its own audio culling system in Project Settings > Audio, which provides configurable Real and Virtual voices. I do not believe the audio culling provided by Unity is making much difference, as it appears all voices are active and none are culled when monitoring the Audio Profiler in Game Mode, despite the emitter being far enough away to be culled.
I’ve exhausted my debugging of that issue for now. I saw a big performance boost when dynamically enabling/disabling Audio and Csound components with the AudioCullingManager script. Though i’m yet to find out if the performance is still much better after fixing the no sound issue with the AudioCulling script.
That’s all for now, thanks!!