- 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.