GetComponent Cannot convert 'UnityEngine.Component'

The Unity3d docs on GetComponent says:

function Update () {
    var other : ScriptName = gameObject.GetComponent(ScriptName);
    other.DoSomething ();
}

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?

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:

var menuElement : MenuElement = gameObject.GetComponent<MenuElement>();

?

function Init ()
{
	playerGameData = transform.root.GetComponent<PlayerGameData>();
}

I tried this, but I get the following :

Are you sure ? Isn’t it a C# specific feature ?

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.

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… :confused:

Try this:

var menuElement : MenuElement = GetComponent(MenuElement);

or

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

and see if it works.

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:

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

Hello Eric.

I am having the same problem with #pragma strict.

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

private var function_Gamobj : GameObject;
var function_Javscr : Function_Javscr;

function_Gamobj = new GameObject ("Function_Gamobj");
function_Gamobj.AddComponent ("Function_Javscr");
function_Javscr = function_Gamobj.GetComponent("Function_Javscr");
print(function_Javscr.test_Int);

Thanks.

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?

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.

If you’re doing iOS development then you can’t use dynamic typing and must use #pragma strict.

–Eric