Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Seemingly incorrectly using GetComponentInChildren caused SetActive calls not work work, Why?

Discussion in 'UGUI & TextMesh Pro' started by Juxtaposed, Nov 24, 2019.

  1. Juxtaposed

    Juxtaposed

    Joined:
    Aug 23, 2015
    Posts:
    29
    The following code compiled but the lines that called SetActive on the button or input field did not do anything nor did the lines that set the text for the button.

    After trying for some time to find out what I was doing wrong I noticed that I was not using the text mesh pro version of the button. So I changed it not expecting it to fix my problem. But after I changed the following type of line:

    theButton.GetComponentInChildren<Text>().text = "Draw";

    to:

    theButton.GetComponentInChildren<TextMeshPro>().text = "Draw";

    Things still didn't work. But after I changed it to

    theButton.GetComponentInChildren<TextMeshProUGUI>().text = "Draw";

    Both the changing of the text worked and the SetActive calls worked.

    I imagine that there must not actually be a Text component on the standard button component, and there isn't a TextMeshPro component on the Text Mesh Pro version of the button, but there is a TextMeshProUGUI component, and this is why correcting this would fix the code to work to change the text on the TextMeshPro buttons. (What component should be used to change the text on the standard button?)

    So this is actually the biggest question I want answered. WHY WOULD CHANGING THIS MAKE THE SETACTIVE CALLS WORK? I'm at a loss.

    This is the original code that did not work:

    Code (CSharp):
    1. void Awake()
    2.     {
    3.         textOut("How many 1's?");
    4.         userInput.keyboardType = TouchScreenKeyboardType.NumberPad;
    5.         userInput.contentType = TMP_InputField.ContentType.IntegerNumber;
    6.         userInput.enabled = true;          
    7.         theButton.GetComponentInChildren<Text>().text = "Draw";
    8.         userInput.gameObject.SetActive(true);
    9.         theButton.gameObject.SetActive(false);
    10.         theButton.enabled = false;
    11.     }
    12.  
    13.     public void actOnUserInput()
    14.     {
    15.         switch(UserInputHandler)
    16.         {
    17.             default:
    18.             case UserInputStep.numberOfOnes:
    19.                 ones = int.Parse(userInput.text);
    20.                 textOut("How many 2's?");
    21.                 UserInputHandler = UserInputStep.numberOfTwos;
    22.                 break;
    23.             case UserInputStep.numberOfTwos:              
    24.                 twos = int.Parse(userInput.text);
    25.                 if(twos > 4)
    26.                 {
    27.                     textOut("Value must be less than 5!");
    28.                 }
    29.                 else
    30.                 {
    31.                     textOut("How many 3's?");
    32.                     UserInputHandler = UserInputStep.numberOfThrees;
    33.                 }              
    34.                 break;
    35.             case UserInputStep.numberOfThrees:
    36.                 threes = int.Parse(userInput.text);
    37.                 Shuffle();
    38.                 textOut("Ready");
    39.                 userInput.enabled = false;
    40.                 UserInputHandler = UserInputStep.numberOfOnes;
    41.                 userInput.gameObject.SetActive(false);
    42.                 theButton.enabled = true;              
    43.                 buttonHandler = buttonFunction.draw;
    44.                 theButton.gameObject.SetActive(true);
    45.                 break;
    46.         }
    47.     }
    48.     public void actOnButtonPress()
    49.     {
    50.         switch (buttonHandler)
    51.         {
    52.             case buttonFunction.draw:
    53.                 theButton.enabled = true;
    54.                 if (stack[0] != 0)
    55.                 {
    56.                     textOut("this should be replaced");
    57.                     textOut(stack[0].ToString());
    58.                     for (int RiseUp = 0; RiseUp < 21; RiseUp++)
    59.                     {
    60.                         stack[RiseUp] = stack[RiseUp + 1];
    61.                     }
    62.                     stack[21] = 0;
    63.                 }
    64.                 else
    65.                 {
    66.                     textOut("Blip stack empty");
    67.                     buttonHandler = buttonFunction.restart;
    68.                     theButton.GetComponentInChildren<Text>().text = "Reset";
    69.                 }
    70.                 break;
    71.             default:
    72.             case buttonFunction.restart:
    73.                 textOut("How Many 1's?");
    74.                 theButton.enabled = false;
    75.                 userInput.enabled = true;
    76.                 userInput.gameObject.SetActive(true);
    77.                 UserInputHandler = UserInputStep.numberOfOnes;
    78.                 buttonHandler = buttonFunction.draw;
    79.                 theButton.GetComponentInChildren<Text>().text = "Draw";
    80.                 theButton.gameObject.SetActive(false);
    81.                 break;
    82.  
    83.         }      
    84.     }

    This is the code that does work:

    Code (CSharp):
    1.     void Awake()
    2.     {
    3.         textOut("How many 1's?");
    4.         userInput.text = "";
    5.         userInput.keyboardType = TouchScreenKeyboardType.NumberPad;
    6.         userInput.contentType = TMP_InputField.ContentType.IntegerNumber;
    7.         userInput.enabled = true;          
    8.         theButton.GetComponentInChildren<TextMeshPro>().text = "Draw";
    9.         userInput.gameObject.SetActive(true);
    10.         theButton.gameObject.SetActive(false);
    11.         theButton.enabled = false;
    12.     }
    13.  
    14.     public void actOnUserInput()
    15.     {
    16.         switch(UserInputHandler)
    17.         {
    18.             default:
    19.             case UserInputStep.numberOfOnes:
    20.                 ones = int.Parse(userInput.text);
    21.                 textOut("How many 2's?");
    22.                 userInput.text = "";
    23.                 UserInputHandler = UserInputStep.numberOfTwos;
    24.                 break;
    25.             case UserInputStep.numberOfTwos:              
    26.                 twos = int.Parse(userInput.text);
    27.                 if(twos > 4)
    28.                 {
    29.                     textOut("Value must be less than 5!");
    30.                 }
    31.                 else
    32.                 {
    33.                     textOut("How many 3's?");
    34.                     userInput.text = "";
    35.                     UserInputHandler = UserInputStep.numberOfThrees;
    36.                 }              
    37.                 break;
    38.             case UserInputStep.numberOfThrees:
    39.                 threes = int.Parse(userInput.text);
    40.                 Shuffle();
    41.                 userInput.text = "";
    42.                 textOut("Ready");
    43.                 userInput.enabled = false;
    44.                 UserInputHandler = UserInputStep.numberOfOnes;
    45.                 userInput.gameObject.SetActive(false);
    46.                 theButton.enabled = true;              
    47.                 buttonHandler = buttonFunction.draw;
    48.                 theButton.gameObject.SetActive(true);
    49.                 break;
    50.         }
    51.     }
    52.     public void actOnButtonPress()
    53.     {
    54.         if(displayText.text == "Ready")
    55.         {
    56.             textOut("");
    57.         }
    58.         switch (buttonHandler)
    59.         {
    60.             case buttonFunction.draw:
    61.                 theButton.enabled = true;
    62.                 if (stack[0] != 0)
    63.                 {                  
    64.                     textOut(displayText.text + stack[0].ToString() + "\n");
    65.                     for (int RiseUp = 0; RiseUp < 21; RiseUp++)
    66.                     {
    67.                         stack[RiseUp] = stack[RiseUp + 1];
    68.                     }
    69.                     stack[21] = 0;
    70.                 }
    71.                 else
    72.                 {
    73.                     textOut(displayText.text + "Blip stack empty");
    74.                     buttonHandler = buttonFunction.restart;
    75.                     theButton.GetComponentInChildren<TextMeshPro>().text = "Reset";
    76.                 }
    77.                 break;
    78.             default:
    79.             case buttonFunction.restart:
    80.                 textOut("How Many 1's?");
    81.                 theButton.enabled = false;
    82.                 userInput.enabled = true;
    83.                 userInput.gameObject.SetActive(true);
    84.                 UserInputHandler = UserInputStep.numberOfOnes;
    85.                 buttonHandler = buttonFunction.draw;
    86.                 theButton.GetComponentInChildren<TextMeshPro>().text = "Draw";
    87.                 theButton.gameObject.SetActive(false);
    88.                 break;
    89.  
    90.         }      
    91.     }
     
  2. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,833
    If you take a look in the Unity console, you'll probably find that when you were trying to get the incorrect component, it generated a run-time error. When your code has an error (and you don't handle it yourself), Unity stops executing that function, so any lines after the error occurred won't run.

    When you use GetComponent (or its relatives) to try to get a component that doesn't exist, it returns a special value called "null" that means there's nothing there. If you want to be on the safe side, you can assign the component you got to a variable and check whether it's null before you try to use it. If you just go ahead and use it without checking, and it turns out to be null, that causes a Null Reference Exception.
     
    Juxtaposed likes this.
  3. Juxtaposed

    Juxtaposed

    Joined:
    Aug 23, 2015
    Posts:
    29
    Thanks much. I'm not experienced enough with code that could end up with null references to think about that myself but after reading your explanation it makes a lot of sense. I'm more familiar with coding for microcontrollers.

    Is there any way to get run-time error logs when running an Android app? And along that same line, is there any way to set break points and debug while running an Android app on a phone?
     
  4. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,833
    You may find it helpful to test using Unity Remote before you make a build on the actual device.

    I'm not entirely sure what options you have for debugging an Android build. I believe there's a system log you can look at, but it usually includes a ton of stuff that you're not interested in, which makes it a chore to wade through.