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

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,181
    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.