Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Resolved One solution to "GetComponentsInChildren returning parent's component aswell?"

Discussion in 'Scripting' started by FlavsSilva, Nov 7, 2023.

  1. FlavsSilva

    FlavsSilva

    Joined:
    May 28, 2018
    Posts:
    4
    First time posting a thread so I apologize in advance if its not completely correct. I just wanted to post this because it upsets me how usls some of the unity support is and whoever is responsible for not making a solution to this API that would simply have an extra option to "ExcludeParent".

    This simple solution worked for any component that I wanted.

    Credit to @Vadimskyi on this post https://forum.unity.com/threads/getcomponentsinchildren-not-parent-and-children.222009/ is where he posted this solution but its a bit buried and hidden in the thread



    private MonoBehaviour[] childrenScripts;

    void Awake()
    {
    childrenScripts = GetComponentsInChildren<MonoBehaviour>();
    }

    void Update()
    {
    foreach (var script in childrenScripts)
    {
    //Ignore the parent's monobehavior
    if (script == this.GetComponent<MonoBehaviour>())
    continue;

    script.enabled = true;
    }
    }
     
    Last edited: Nov 7, 2023
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,158
    It likely upsets some of the Unity staff who are being called useless too. Because you don't like how a method works is no reason to be rude so please, discuss but be respectful to all.

    The docs state quite clearly its function and this subject has been discussed to death on these forums, even recently here.

    Side-note: How to post code on the forums.

    Thanks.
     
  3. FlavsSilva

    FlavsSilva

    Joined:
    May 28, 2018
    Posts:
    4
    Ok I will apologize for my rudeness it was unnecessary and uncalled for but the criticism should still stand as this has been a problem for years now like you said it has been discussed to death. This also has happened an incredible amount times. Once again I apologize but I do think I am being fair with the criticism as in 5 years of me programming most of the solutions on these forums that are more clearly stated and better in implementation come from the community and almost never from the support.
     
  4. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,344
    That solution is also pretty terrible and I don't think actually works as you think it does. Using
    this.GetComponent<Monobehaviour>
    will return the first monobehaviour component on the same game object as the calling component (their order matters). Which means if there's another monobehaviour before this component on a game object, you'll be comparing against that and skipping past it, leaving you to possible still be iterating on the same instance as
    this
    .

    If your intent is to skip the same component invoking the call, then you want to compare against
    this
    . Ergo:
    Code (CSharp):
    1. foreach (var component in childrenComponents)
    2. {
    3.     if (component == this)
    4.     {
    5.         continue;
    6.     }
    7. }
    (fyi they're components, not scripts).

    Or if you intend to skip all components on the same game object that was the root call for
    GetComponentsInChildren<T>
    then you want to compare each component's game object, like so:
    Code (CSharp):
    1. foreach (var component in childrenComponents)
    2. {
    3.     if (component.gameObject == this.gameObject)
    4.     {
    5.         continue;
    6.     }
    7. }
    So if we're trying to provide solutions let's first make sure they're actually working ones.
     
  5. FlavsSilva

    FlavsSilva

    Joined:
    May 28, 2018
    Posts:
    4
    Fair enough, but this will also be considered a different problem right? Finding all scripts or the one that you specifically want in the children or parent. This code implementation mostly to show how to skip the parent for the GetComponentsInChildren API. In case I am once again wrong do please correct me for future devs to have this solution completely solved.
     
  6. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,344
    That's the thing. Your code doesn't. It only skips the first monobehaviour component on the same game object, which is very unlikely to be the behaviour anyone wants. If there's multiple monobehaviours on said game object then you won't skip any beyond the first.

    My solutions skips the same component in the first example, and the parent game object in the second example (the problem you were trying to solve).

    Unity support isn't there to teach you how to code.
     
  7. FlavsSilva

    FlavsSilva

    Joined:
    May 28, 2018
    Posts:
    4
    And yet, point was proven once again, its like a firefighter telling you where the bucket and water are so you can go and put the fire out yourself, or ask your neighbors to help. Thanks for the solution though.
     
  8. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,158
    What "fire" though? :)