Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Understanding MonoBehaviour and enabling/disabling child components [SOLVED]

Discussion in 'Scripting' started by QuinnWinters, Feb 28, 2015.

  1. QuinnWinters

    QuinnWinters

    Joined:
    Dec 31, 2013
    Posts:
    494
    I'm attempting to understand some code from an example I'm working from, and also to remove an error from it. I'll start with the error, "enabled is not a member of component." The following script runs great if I comment out #pragma strict. But I'm pretty sure that once the script is compiled and runs outside the editor it's still going to cause an error. How would I go about doing the same thing that's done in this example but without the error, which derives from trying to set a non-existent enabled property on components.

    Second, I do not understand the line "var thisComponent : MonoBehaviour = eachComponent as MonoBehaviour;" The way that reads to me, from my understanding of MonoBehaviour, is "thisComponent is a member of a class that's equal to the class of each component in the componentsToEnable array." That doesn't really make any sense to me. Could someone please explain that line to me?
    Code (JavaScript):
    1. //#pragma strict
    2. var myObjects : GameObject[];
    3.  
    4. function ThisFunction (i : int) {
    5.  
    6.     var componentsToEnable : Component[] = myObjects[i].gameObject.GetComponentsInChildren(MonoBehaviour);
    7.    
    8.     for (var eachComponent in componentsToEnable) {
    9.         var thisComponent : MonoBehaviour = eachComponent as MonoBehaviour;
    10.         if (thisComponent) {
    11.             eachComponent.enabled = true;
    12.         }
    13.     }
    14.  
    15. }
     
  2. Ruekaka

    Ruekaka

    Joined:
    Sep 12, 2014
    Posts:
    119
    The error/warning occurs because eachComponent is of the type Component which has no property enabled. I assume the author had planned to write
    Code (JavaScript):
    1. thisComponent.enabled = true;
    That's also the answer to the second question, because in this line
    Code (CSharp):
    1. var thisComponent : MonoBehaviour = eachComponent as MonoBehaviour;
    the author casts the Component to MonoBehaviour.
     
  3. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    This part:
    Code (JavaScript):
    1. var thisComponent : MonoBehaviour
    is creating a new variable called "thisComponent" and saying that the variable is ONLY going to be used to store data of type "MonoBehavior".

    This part:
    Code (JavaScript):
    1. eachComponent as MonoBehaviour
    is saying that even though the variable "eachComponent" doesn't necessarily contain an object of type "MonoBehavior", you think it might, so you're going to try to cast (reinterpret) the value of "eachComponent" as if it were a "MonoBehavior". This might or might not be successful. If it succeeds, the expression evaluates to a MonoBehavior; if it fails (because eachComponent contains some other kind of data), then it evaluates to null.

    The equals sign, of course, evaluates the right-hand side (eachComponent as MonoBehavior) and stores it in the left-hand side (a variable called "thisComponent", which can only store data of type MonoBehavior).

    The next line--"if (thisComponent)"--then checks whether your cast was successful. If the cast failed, then "thisComponent" will have the value "null", and the "if" will be considered false. But if the cast succeeded, then the "if" will be considered true.

    So the entire thing together is saying "do this thing to all of the components that are MonoBehaviors, but ignore the components that aren't MonoBehaviors".
     
  4. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    The original code is written badly. Here is a more elegant solution to the same problem.

    Code (JavaScript):
    1. //#pragma strict
    2. var myObjects : GameObject[];
    3.  
    4. function ThisFunction (i : int) {
    5.  
    6.     var componentsToEnable : Component[] = myObjects[i].gameObject.GetComponentsInChildren(MonoBehaviour);
    7.  
    8.     for (var eachComponent : MonoBehaviour in componentsToEnable) {
    9.             eachComponent.enabled = true;
    10.     }
    11.  
    12. }
    You might be able to simplify even further by changing the type of componentsToEnable from Component[] to MonoBevahiour[]. It would work in C#, but my JavaScript is weak
     
  5. QuinnWinters

    QuinnWinters

    Joined:
    Dec 31, 2013
    Posts:
    494
    Thanks for the replies. BoredMormon's solution got rid of the error and makes sense when I read it. The example I'm working from isn't the greatest example in the world, it was very sloppily written all around and I've been having to clean it up just to be able to read it so I'm not surprised that bit was written badly. Much appreciated guys.