Search Unity

GetComponent Cannot convert 'UnityEngine.Component'

Discussion in 'Scripting' started by alph, Oct 20, 2010.

  1. alph

    alph

    Joined:
    Jul 20, 2010
    Posts:
    89
    The Unity3d docs on GetComponent says:
    Code (csharp):
    1.  
    2. function Update () {
    3.     var other : ScriptName = gameObject.GetComponent(ScriptName);
    4.     other.DoSomething ();
    5. }
    All I'm doing is substituting ScriptName with MenuElement (my script is called MenuElement.js), and that gives the error:

    MenuElement.js(26,86): BCE0022: Cannot convert 'UnityEngine.Component' to 'MenuElement'.

    If I however add "as MenuElement" after GetComponent it works.

    My question is this: Is the docs slightly in error here, or am I doing something wrong?
     
  2. tomvds

    tomvds

    Joined:
    Oct 10, 2008
    Posts:
    1,028
    It's a mistake in the docs. This used to work in 2.6, but in Unity3, it no longer auto-casts your GetComponent result.

    Edit: it turns out that the remaining text of this post is incorrect
    If you wish to avoid the 'as MenuElement', use this:
    Code (csharp):
    1. var menuElement : MenuElement = gameObject.GetComponent<MenuElement>();
     
    Last edited: Oct 20, 2010
  3. AkilaeTribe

    AkilaeTribe

    Joined:
    Jul 4, 2010
    Posts:
    1,149
    ?

    Code (csharp):
    1. function Init ()
    2. {
    3.     playerGameData = transform.root.GetComponent<PlayerGameData>();
    4. }
    I tried this, but I get the following :

    Are you sure ? Isn't it a C# specific feature ?
     
  4. tomvds

    tomvds

    Joined:
    Oct 10, 2008
    Posts:
    1,028
    Yes, sorry about that. I was under the impression, that (with generics now supported in JS) the generic Unity functions would also work for JS. Apparently I was wrong. Perhaps someone with more hands-on JS experience knows why it doesn't work.
     
  5. alph

    alph

    Joined:
    Jul 20, 2010
    Posts:
    89
    Seems to me the as ScriptName is quite abdundant, since 99% of the time it's the script you want, not the Component class.. It's strange though that it seems like sometimes you need it and sometimes you dont.. :/
     
  6. TerryNorton

    TerryNorton

    Joined:
    Jun 6, 2008
    Posts:
    24
    Try this:

    var menuElement : MenuElement = GetComponent(MenuElement);

    or

    var menuElement : MenuElement = this.GetComponent(MenuElement);

    and see if it works.
     
  7. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    No, it still works fine in Unity 3. The exception is if you're using #pragma strict. In which case, you can add #pragma downcast and then it will allow downcasting like Unity 2.6 did.

    The correct syntax in JS is:

    Code (csharp):
    1. var menuElement = gameObject.GetComponent.<MenuElement>();
    You could do "var menuElement : MenuElement" if you want to be 100% explicit, but it seems a bit redundant here.

    That's why you add "as ScriptName", since GetComponent returns Component, so you have to cast it as ScriptName. Unless you're using dynamic typing or #pragma downcast.

    Not actually strange...if you're using dynamic typing or #pragma downcast, you don't need it. Otherwise you do.

    --Eric
     
  8. iEarthHero1

    iEarthHero1

    Joined:
    Jul 28, 2009
    Posts:
    301
    Hello Eric.

    I am having the same problem with #pragma strict.

    How do I get the following code to work without downcasting?

    Code (csharp):
    1. private var function_Gamobj : GameObject;
    2. var function_Javscr : Function_Javscr;
    3.  
    4. function_Gamobj = new GameObject ("Function_Gamobj");
    5. function_Gamobj.AddComponent ("Function_Javscr");
    6. function_Javscr = function_Gamobj.GetComponent("Function_Javscr");
    7. print(function_Javscr.test_Int);
    Thanks.
     
  9. DocSWAB

    DocSWAB

    Joined:
    Aug 28, 2006
    Posts:
    615
    Maybe I'm just being superstitious, but I have found that with #pragma strict, I've had to both declare the variable AND use the at:

    var newItem : Classname = gameObject.GetComponent(Classname) as Classname;

    Seems pretty redundant, and Eric suggests not all those are needed, but I've had a hard time getting some of the scripts to work without doing both. Is that crazy?
     
  10. iEarthHero1

    iEarthHero1

    Joined:
    Jul 28, 2009
    Posts:
    301
    Thanks.

    However, this was a hang up that I burned up a couple hours trying to figure out. I find myself fearful that there will be many other "hang ups" related to using #pragma strict that will also be remarkably time consuming to figure out.

    Can anyone else provide insight into whether there will only be a couple other hang ups or if there will be a laundry list of difficulties just like this one?

    I am thinking for the sake of productivity I may just go back to dynamic typing.

    Thanks.
     
  11. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    If you're doing iOS development then you can't use dynamic typing and must use #pragma strict.

    --Eric