Search Unity

[Answered] Why this method does not work properly?

Discussion in 'Scripting' started by Kagyu, Aug 2, 2020.

  1. Kagyu

    Kagyu

    Joined:
    Mar 5, 2016
    Posts:
    96
    Hi.
    I have just created a simple method which try to unify the all UI selectable elements' color block at once.
    Code (CSharp):
    1.     public void Unify(GameObject parent)
    2.     {
    3.         //initialize colorBlock
    4.         ColorBlock colorBlock = new ColorBlock();
    5.         colorBlock.normalColor = normalColor;
    6.         colorBlock.highlightedColor = hilightedColor;
    7.         colorBlock.pressedColor = pressedColor;
    8.         colorBlock.selectedColor = selectedColor;
    9.         colorBlock.disabledColor = disabledColor;
    10.  
    11.         int i = 0;
    12.  
    13.         List<GameObject> uiElements = GetAllChildren.GetAll(parent);
    14.         foreach(GameObject go in uiElements)
    15.         {
    16.             if (go.GetComponent<Selectable>() != null)
    17.             {
    18.                 go.GetComponent<Selectable>().colors = colorBlock;
    19.  
    20.                 i++;
    21.             }
    22.         }
    23.  
    24.         Debug.Log($"<color=cyan>{i} UI selectable elements has been modified.</color>");
    25.     }
    When I call the function above, all ui selectable elements seems to be applied proper color in the editor property, but all of them displayed in grey and no selectedColor and/or pressedColor applied in the game view.
    2020-08-02.png
    Instead doing above, by modifying the function as below, everything works just perfect but I do not understand what is the difference.
    Code (CSharp):
    1.     public void Unify(GameObject parent)
    2.     {
    3.  
    4.         int i = 0;
    5.  
    6.         List<GameObject> uiElements = GetAllChildren.GetAll(parent);
    7.         foreach(GameObject go in uiElements)
    8.         {
    9.             if (go.GetComponent<Selectable>() != null)
    10.             {
    11.                 var colors = go.GetComponent<Selectable>().colors;
    12.                 colors.normalColor = normalColor;
    13.                 colors.highlightedColor = hilightedColor;
    14.                 colors.pressedColor = pressedColor;
    15.                 colors.selectedColor = selectedColor;
    16.                 colors.disabledColor = disabledColor;
    17.                 go.GetComponent<Selectable>().colors = colors;
    18.  
    19.                 i++;
    20.             }
    21.         }
    22.  
    23.         Debug.Log($"<color=cyan>{i} UI selectable elements has been modified.</color>");
    24.     }
    I should be misunderstand something. If anyone kindly could point out what it is, please do so.
     
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,909
    In the second version of the script you are first copying the existing ColorBlock, then just modifying a few fields, and writing it back. This means that other fields besides the colors you are modifying are staying the same on the ColorBlock. This includes colorMultiplier, fadeDuration, etc... https://docs.unity3d.com/Packages/c...ock#UnityEngine_UI_ColorBlock_colorMultiplier

    In your first version you are creating a new ColorBlock. In a struct, the default new operator simply populates the struct with the "default" value for each type. That means 0 for floats, 0,0,0,0 colors, etc... (notice the 0s in the fields in your screenshot for Fade Duration etc) they might not be sensible values. But the copy you pull in the second version will have sensible values for these other fields.
     
  3. Kagyu

    Kagyu

    Joined:
    Mar 5, 2016
    Posts:
    96
    I see!
    I needed to look into the ColorBlock property in the link to study what it was. Now I understand why and it is not only about five colors for the element.
    Thank you so much for the teaching!

    p.s. BTW He/she looks cute just as how my cat does!
     
    Last edited: Aug 4, 2020