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

4.6 -Component or Slider? "onValueChanged' is not a member of 'UnityEngine.Component"

Discussion in 'UGUI & TextMesh Pro' started by mipo, Oct 22, 2014.

  1. mipo

    mipo

    Joined:
    Aug 22, 2013
    Posts:
    19
    In this snippet p is a RectTransform I have just instantiated.

    It is a UI.panel, that contains 3 sliders.
    When I do this:

    var content = p.GetComponentsInChildren(UnityEngine.UI.Slider);
    for (var sl : UnityEngine.UI.Slider in content)
    {
    print(sl.GetType()); // prints 'UnityEngine.UI.Slider'
    sl.onValueChanged.AddListener(SetRadius);
    }
    print(content[0].GetType());// prints 'UnityEngine.UI.Slider'

    I get no error. The listener is added to the three
    sl sliders. And both sl and content[0] appear to be of the same type: UnityEngine.UI.Slider

    If I try to do this however (in order to assign a different listener to each slider):

    content[0].onValueChanged.AddListener(SetSpeed);

    I get an onValueChanged' is not a member of 'UnityEngine.Component error.

    Why are content members identified as
    UnityEngine.UI.Slider when asked by GetType() yet considered a component when I address them with content[index]?

    If I try to initialize my content variable like this:

    var content : UnityEngine.UI.Slider[] = p.GetComponentsInChildren(UnityEngine.UI.Slider);

    It passes first assembly, but at runtime, it throws the InvalidCastException: Cannot cast from source type to destination type. error.

    This is very confusing. How do I access the members of content as UI.Sliders?
     
  2. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,221
    The array is of type Object[] and you are trying to cast it to Slider[], this is invalid.

    Instead you want to cast each element of the array to a Slider:

    var components = p.GetComponentsInChildren(UnityEngine.UI.Slider).Length;
    for (int i =0; i<components.Length; i++)
    {
    ((Slider)components).onValueChanged.AddListener(SetSpeed);
    }
     
    mipo likes this.
  3. mipo

    mipo

    Joined:
    Aug 22, 2013
    Posts:
    19
    Ok Thanks Tim, but then why does this output UnityEngine.UI.Slider as its type?

    print(content[0].GetType());


    ((Slider)components) ?


    Now, how do I cast to a different type (in Javascript)?
    The following gives me an invalid cast exception at runtime:

    var content : UnityEngine.UI.Slider[] = p.GetComponentsInChildren(UnityEngine.UI.Slider);

    This gives me a UnityEngine not a member of component error:

    content[0].UnityEngine.UI.Slider.onValueChanged.AddListener(SetRadius);

    And this throws the Object reference is not set to an instance of an object error:

    var content = p.GetComponentsInChildren(UnityEngine.UI.Slider) as UnityEngine.UI.Slider[];

    on the line where I do I do content[0].onValueChanged.AddListener(SetRadius);
     
  4. leftchannel

    leftchannel

    Joined:
    Feb 28, 2014
    Posts:
    25
    Because the array is type Object[], but once you get the individual array items, they all know their own type. This is true of any inherited type.
     
    mipo likes this.
  5. mipo

    mipo

    Joined:
    Aug 22, 2013
    Posts:
    19
    OK, I found a way:
    If I store my array element in a variable and cast that variable as a slider then it works....

    var content = p.GetComponentsInChildren(UnityEngine.UI.Slider);
    var sl1 : UnityEngine.UI.Slider = content[0];
    sl1.onValueChanged.AddListener(SetRadius);
     
  6. jdyeager

    jdyeager

    Joined:
    Aug 18, 2008
    Posts:
    29
    Your original code was working in the foreach because the loop was doing an implicit cast when it assigned a value to the 'sl' variable. It's basically the same as what you're doing now when you create a variable of type Slider and assign it a value from the content array.
     
    mipo likes this.