- Home /
Using GetComponentsInChildren to detect renderer
I am trying to modify a script that detects if an object is in direct view, and if so, to crossfade between 2 audio sources. The code is below:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Audio;
public class CameraAudioCtrl2 : MonoBehaviour {
public Transform playerCamera;
public Transform audioObject;
public AudioSource unfiltered;
public AudioSource filtered;
public float distanceThreshold;
public float distance;
public float rampTimeGrain;
// Start is called before the first frame update
void Start()
{
renderer = GetComponentsInChildren<Transform>();
}
// Update is called once per frame
void Update()
{
distance = Vector3.Distance(playerCamera.position, audioObject.position);
if(audioObject.GetComponent<Renderer>().isVisible && distance < distanceThreshold)
{
if(unfiltered.volume > 0.0f)
unfiltered.volume -= rampTimeGrain;
if(filtered.volume < 1.01f)
filtered.volume += rampTimeGrain;
}
else
{
if(unfiltered.volume < 1.0f)
unfiltered.volume += rampTimeGrain;
if(filtered.volume > 0.0f)
filtered.volume -= rampTimeGrain;
}
}
}
The script is attached to the main camera, and audioObject is the game object that has a renderer attached. I was advised to use GetComponentsInChildren ([presumably because the game objects are prefabs), but when I run the script I am told the game object does not have a renderer attached to it. I'm fairly new at scripting so I'm probably missing something obvious. Does anyone have an idea of what I might be doing wrong here?
Answer by Mouton · Sep 26, 2019 at 01:06 PM
In your Start event, you are retrieving Transform components and not Renderer component. On top of that, you are using the method GetComponentsInChildren, which is plural and will return an array of components, not a single component. Use the GetComponentInChildren (without the "s") instead.
void Start()
{
renderer = GetComponentInChildren<Renderer>();
}
Thank you! I hadn't meant to put Transform in there actually. I'll try the singular approach for the GetComponent call.
Now when changing to the above I get this error:
'Component.renderer' is obsolete: 'Property renderer has been deprecated. Use GetComponent() ins$$anonymous$$d. (UnityUpgradable)'
Use $$anonymous$$eshRenderer type and rename your variable meshRenderer ins$$anonymous$$d:
void Start()
{
meshRenderer = GetComponentInChildren<$$anonymous$$eshRenderer>();
}
I took a slightly different approach in the end, creating a totally new game object with a renderer attached, and referencing that in the script ins$$anonymous$$d. But now I have a different problem. It appears that I cannot enact this same behavior on two separate objects in the scene. If I attach 2 instances of the script to the main camera, and point them at different game objects, only one of them triggers the audio behavior at any given time. I have switched one of the two scripts off to validate this and sure enough, when only one instance is enabled it works fine. Is there a solution to this?
The fact that it does not work with 2 instances of the script is because of the if/else condition in the for loop: each script check the condition and change the filtered/unfiltered values, thus only the second script in the execution loop will change the value.
Your answer