[SOLVED] UI CANVAS : GameObject.GetComponentsInChildren

Hi,

The code I use allows to enabled/disable a canvas when the camera see a QRCode, until now I used the code below:

        //enable canvas
        Canvas canvasObject = (Canvas) FindObjectOfType(typeof(Canvas));
        {
            canvasObject.enabled = true;
        }
        //disable canvas
        Canvas canvasObject = (Canvas) FindObjectOfType(typeof(Canvas));
        {
            canvasObject.enabled = false;
        }

The problem is with several different canvas, Unity enabled/disable just the first canvas found…

I would like to use the function GameObject.GetComponentsInChildren with the canvas instead of the function FindObjectOfType ?

I tried with the help offered by Unity3D website, but without success. Thank you in advance for your help !

if you put all your canvases under a single game object, and your script knows about that parent gameobject then the GetComponentInChildren will work for you.

The other option is to specify a list of Canvases to run through. if you know them all at edit time you can do it via the inspector. If you need it at run time you will need to come up with a way to gather all the canvases

Thanks @phil-Unity for you answer, but i don’t understand your second sentence, i started in Unity3D :wink: I would like use the function GetComponentsInChildren with canvasses, but i don’t know write the code…

If i put my canvas in a empty “GameObject”, this code is correct ?

    private void OnTrackingFound()
    {
        Renderer[] rendererComponents = GetComponentsInChildren<Renderer>(true);
        Collider[] colliderComponents = GetComponentsInChildren<Collider>(true);

        //enable canvas
               public GameObject[] GameObject;
               void Example() {
                        GameObject = gameObject.GetComponentsInChildren<GameObject>();
        {
            gameObject.enabled = true;
        }
        }
    }

I usually dont do this as it tends to come back as i dont test the example code i write but something like the following should do what you need.

public class MyClass
{
    public GameObject parentObject;

    public void MyFunction()
    {
        Canvas[] canvasObjects = parentObject.GetComponentInChildren<Canvas>();
       
        foreach(Canvas canvas in canvasObjects)
        {
            canvas.gameobject.enabled = true;
        }
    }
}
1 Like

Thanks @phil-Unity but it doesn’t work :face_with_spiral_eyes: There are 2 error messages for each “Canvas function” :

Assets/Qualcomm Augmented Reality/Scripts/DefaultTrackableEventHandler.cs(72,26): error CS0029: Cannot implicitly convert type UnityEngine.Canvas' to UnityEngine.Canvas[ ]’

Assets/Qualcomm Augmented Reality/Scripts/DefaultTrackableEventHandler.cs(77,32): error CS1061: Type UnityEngine.Canvas' does not contain a definition for gameobject’ and no extension method gameobject' of type UnityEngine.Canvas’ could be found (are you missing a using directive or an assembly reference?)

COMPLETE CODE

using UnityEngine;

/// <summary>
/// A custom handler that implements the ITrackableEventHandler interface.
/// </summary>
public class DefaultTrackableEventHandler : MonoBehaviour,
                                            ITrackableEventHandler
{
    #region PRIVATE_MEMBER_VARIABLES
    private TrackableBehaviour mTrackableBehaviour;
  
    #endregion // PRIVATE_MEMBER_VARIABLES



    #region UNTIY_MONOBEHAVIOUR_METHODS
  
    void Start()
    {
        mTrackableBehaviour = GetComponent<TrackableBehaviour>();
        if (mTrackableBehaviour)
        {
            mTrackableBehaviour.RegisterTrackableEventHandler(this);
        }
    }

    #endregion // UNTIY_MONOBEHAVIOUR_METHODS



    #region PUBLIC_METHODS

    /// <summary>
    /// Implementation of the ITrackableEventHandler function called when the
    /// tracking state changes.
    /// </summary>
    public GameObject parentObject;
    public void OnTrackableStateChanged(
                                    TrackableBehaviour.Status previousStatus,
                                    TrackableBehaviour.Status newStatus)
    {
        if (newStatus == TrackableBehaviour.Status.DETECTED ||
            newStatus == TrackableBehaviour.Status.TRACKED ||
            newStatus == TrackableBehaviour.Status.EXTENDED_TRACKED)
        {
            OnTrackingFound();
        }
        else
        {
            OnTrackingLost();
        }
    }

    #endregion // PUBLIC_METHODS



    #region PRIVATE_METHODS


    private void OnTrackingFound()
    {
        Renderer[] rendererComponents = GetComponentsInChildren<Renderer>(true);
        Collider[] colliderComponents = GetComponentsInChildren<Collider>(true);
        Canvas[] canvasObjects = parentObject.GetComponentInChildren<Canvas>();



        //enable canvas

        foreach(Canvas canvas in canvasObjects)

        {

            canvas.gameobject.enabled = true;

        }

        // Enable rendering:
        foreach (Renderer component in rendererComponents)
        {
            component.enabled = true;
        }

        // Enable colliders:
        foreach (Collider component in colliderComponents)
        {
            component.enabled = true;
        }

        Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " found");
    }


    private void OnTrackingLost()
    {
        Renderer[] rendererComponents = GetComponentsInChildren<Renderer>(true);
        Collider[] colliderComponents = GetComponentsInChildren<Collider>(true);
        Canvas[] canvasObjects = parentObject.GetComponentInChildren<Canvas>();



        //disable canvas

        foreach(Canvas canvas in canvasObjects)

        {

            canvas.gameobject.enabled = false;

        }

        // Disable rendering:
        foreach (Renderer component in rendererComponents)
        {
            component.enabled = false;
        }

        // Disable colliders:
        foreach (Collider component in colliderComponents)
        {
            component.enabled = false;
        }

        Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " lost");
    }

    #endregion // PRIVATE_METHODS
}

Canvas[ ] canvasObjects = parentObject.GetComponentInChildren(); should be Canvas[ ] canvasObjects = parentObject.GetComponentsInChildren(); (notice the s on components)

canvas.gameobject.enabled=true; needs to be canvas.gameObject.enabled=true; (notice the capital O in gameObject).

This is the exact reason i dont try to write code examples as if i miss one letter or capitalization it always comes back :(.

1 Like

Thanks a lot @phil-Unity , it works !

I custom a little bit your code :slight_smile:

        Canvas[] canvasObjects = GetComponentsInChildren<Canvas>();

        //enable canvas
        foreach(Canvas canvas in canvasObjects)
        {
            canvas.enabled = true;
        }
        Canvas[] canvasObjects = GetComponentsInChildren<Canvas>();

        //disable canvas
        foreach(Canvas canvas in canvasObjects)
        {
            canvas.enabled = false;
        }